{-# LANGUAGE OverloadedStrings #-}
module Distribution.Simple.ShowBuildInfo (
mkBuildInfo, mkBuildInfo', mkCompilerInfo, mkComponentInfo
) where
import System.FilePath
import Distribution.Compat.Prelude
import Prelude ()
import qualified Distribution.Simple.GHC as GHC
import qualified Distribution.Simple.Program.GHC as GHC
import Distribution.PackageDescription
import Distribution.Compiler
import Distribution.Verbosity
import Distribution.Simple.Compiler (Compiler, showCompilerId, compilerFlavor)
import Distribution.Simple.Program
import Distribution.Simple.Setup
import Distribution.Simple.Utils (cabalVersion)
import Distribution.Utils.Json
import Distribution.Types.Component
import Distribution.Types.ComponentLocalBuildInfo
import Distribution.Types.LocalBuildInfo
import Distribution.Types.TargetInfo
import Distribution.Text
import Distribution.Pretty
mkBuildInfo
:: FilePath
-> PackageDescription
-> LocalBuildInfo
-> BuildFlags
-> (ConfiguredProgram, Compiler)
-> [TargetInfo]
-> ([String], Json)
mkBuildInfo :: FilePath
-> PackageDescription
-> LocalBuildInfo
-> BuildFlags
-> (ConfiguredProgram, Compiler)
-> [TargetInfo]
-> ([FilePath], Json)
mkBuildInfo FilePath
wdir PackageDescription
pkg_descr LocalBuildInfo
lbi BuildFlags
_flags (ConfiguredProgram, Compiler)
compilerInfo [TargetInfo]
targetsToBuild = ([FilePath]
warnings, [(FilePath, Json)] -> Json
JsonObject [(FilePath, Json)]
buildInfoFields)
where
buildInfoFields :: [(FilePath, Json)]
buildInfoFields = Json -> [Json] -> [(FilePath, Json)]
mkBuildInfo' ((ConfiguredProgram -> Compiler -> Json)
-> (ConfiguredProgram, Compiler) -> Json
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ConfiguredProgram -> Compiler -> Json
mkCompilerInfo (ConfiguredProgram, Compiler)
compilerInfo) [Json]
componentInfos
componentInfosWithWarnings :: [([FilePath], Json)]
componentInfosWithWarnings = (TargetInfo -> ([FilePath], Json))
-> [TargetInfo] -> [([FilePath], Json)]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
-> PackageDescription
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([FilePath], Json)
mkComponentInfo FilePath
wdir PackageDescription
pkg_descr LocalBuildInfo
lbi (ComponentLocalBuildInfo -> ([FilePath], Json))
-> (TargetInfo -> ComponentLocalBuildInfo)
-> TargetInfo
-> ([FilePath], Json)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TargetInfo -> ComponentLocalBuildInfo
targetCLBI) [TargetInfo]
targetsToBuild
componentInfos :: [Json]
componentInfos = (([FilePath], Json) -> Json) -> [([FilePath], Json)] -> [Json]
forall a b. (a -> b) -> [a] -> [b]
map ([FilePath], Json) -> Json
forall a b. (a, b) -> b
snd [([FilePath], Json)]
componentInfosWithWarnings
warnings :: [FilePath]
warnings = (([FilePath], Json) -> [FilePath])
-> [([FilePath], Json)] -> [FilePath]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([FilePath], Json) -> [FilePath]
forall a b. (a, b) -> a
fst [([FilePath], Json)]
componentInfosWithWarnings
mkBuildInfo'
:: Json
-> [Json]
-> [(String, Json)]
mkBuildInfo' :: Json -> [Json] -> [(FilePath, Json)]
mkBuildInfo' Json
compilerInfo [Json]
componentInfos =
[ FilePath
"cabal-lib-version" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (Version -> FilePath
forall a. Pretty a => a -> FilePath
display Version
cabalVersion)
, FilePath
"compiler" FilePath -> Json -> (FilePath, Json)
.= Json
compilerInfo
, FilePath
"components" FilePath -> Json -> (FilePath, Json)
.= [Json] -> Json
JsonArray [Json]
componentInfos
]
mkCompilerInfo :: ConfiguredProgram -> Compiler -> Json
mkCompilerInfo :: ConfiguredProgram -> Compiler -> Json
mkCompilerInfo ConfiguredProgram
compilerProgram Compiler
compilerInfo = [(FilePath, Json)] -> Json
JsonObject
[ FilePath
"flavour" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (CompilerFlavor -> FilePath
forall a. Pretty a => a -> FilePath
prettyShow (CompilerFlavor -> FilePath) -> CompilerFlavor -> FilePath
forall a b. (a -> b) -> a -> b
$ Compiler -> CompilerFlavor
compilerFlavor Compiler
compilerInfo)
, FilePath
"compiler-id" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (Compiler -> FilePath
showCompilerId Compiler
compilerInfo)
, FilePath
"path" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (ConfiguredProgram -> FilePath
programPath ConfiguredProgram
compilerProgram)
]
mkComponentInfo :: FilePath -> PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> ([String], Json)
mkComponentInfo :: FilePath
-> PackageDescription
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([FilePath], Json)
mkComponentInfo FilePath
wdir PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi = ([FilePath]
warnings, [(FilePath, Json)] -> Json
JsonObject ([(FilePath, Json)] -> Json) -> [(FilePath, Json)] -> Json
forall a b. (a -> b) -> a -> b
$
[ FilePath
"type" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString FilePath
compType
, FilePath
"name" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (ComponentName -> FilePath
forall a. Pretty a => a -> FilePath
prettyShow ComponentName
name)
, FilePath
"unit-id" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (UnitId -> FilePath
forall a. Pretty a => a -> FilePath
prettyShow (UnitId -> FilePath) -> UnitId -> FilePath
forall a b. (a -> b) -> a -> b
$ ComponentLocalBuildInfo -> UnitId
componentUnitId ComponentLocalBuildInfo
clbi)
, FilePath
"compiler-args" FilePath -> Json -> (FilePath, Json)
.= [Json] -> Json
JsonArray ((FilePath -> Json) -> [FilePath] -> [Json]
forall a b. (a -> b) -> [a] -> [b]
map FilePath -> Json
JsonString [FilePath]
compilerArgs)
, FilePath
"modules" FilePath -> Json -> (FilePath, Json)
.= [Json] -> Json
JsonArray ((ModuleName -> Json) -> [ModuleName] -> [Json]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Json
JsonString (FilePath -> Json)
-> (ModuleName -> FilePath) -> ModuleName -> Json
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModuleName -> FilePath
forall a. Pretty a => a -> FilePath
display) [ModuleName]
modules)
, FilePath
"src-files" FilePath -> Json -> (FilePath, Json)
.= [Json] -> Json
JsonArray ((FilePath -> Json) -> [FilePath] -> [Json]
forall a b. (a -> b) -> [a] -> [b]
map FilePath -> Json
JsonString [FilePath]
sourceFiles)
, FilePath
"hs-src-dirs" FilePath -> Json -> (FilePath, Json)
.= [Json] -> Json
JsonArray ((SymbolicPath PackageDir SourceDir -> Json)
-> [SymbolicPath PackageDir SourceDir] -> [Json]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Json
JsonString (FilePath -> Json)
-> (SymbolicPath PackageDir SourceDir -> FilePath)
-> SymbolicPath PackageDir SourceDir
-> Json
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymbolicPath PackageDir SourceDir -> FilePath
forall a. Pretty a => a -> FilePath
prettyShow) ([SymbolicPath PackageDir SourceDir] -> [Json])
-> [SymbolicPath PackageDir SourceDir] -> [Json]
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [SymbolicPath PackageDir SourceDir]
hsSourceDirs BuildInfo
bi)
, FilePath
"src-dir" FilePath -> Json -> (FilePath, Json)
.= FilePath -> Json
JsonString (FilePath -> FilePath
addTrailingPathSeparator FilePath
wdir)
] [(FilePath, Json)] -> [(FilePath, Json)] -> [(FilePath, Json)]
forall a. Semigroup a => a -> a -> a
<> [(FilePath, Json)]
cabalFile)
where
([FilePath]
warnings, [FilePath]
compilerArgs) = BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([FilePath], [FilePath])
getCompilerArgs BuildInfo
bi LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi
name :: ComponentName
name = ComponentLocalBuildInfo -> ComponentName
componentLocalName ComponentLocalBuildInfo
clbi
bi :: BuildInfo
bi = Component -> BuildInfo
componentBuildInfo Component
comp
comp :: Component
comp = Component -> Maybe Component -> Component
forall a. a -> Maybe a -> a
fromMaybe (FilePath -> Component
forall a. HasCallStack => FilePath -> a
error (FilePath -> Component) -> FilePath -> Component
forall a b. (a -> b) -> a -> b
$ FilePath
"mkBuildInfo: no component " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ ComponentName -> FilePath
forall a. Pretty a => a -> FilePath
prettyShow ComponentName
name) (Maybe Component -> Component) -> Maybe Component -> Component
forall a b. (a -> b) -> a -> b
$ PackageDescription -> ComponentName -> Maybe Component
lookupComponent PackageDescription
pkg_descr ComponentName
name
compType :: FilePath
compType = case Component
comp of
CLib Library
_ -> FilePath
"lib"
CExe Executable
_ -> FilePath
"exe"
CTest TestSuite
_ -> FilePath
"test"
CBench Benchmark
_ -> FilePath
"bench"
CFLib ForeignLib
_ -> FilePath
"flib"
modules :: [ModuleName]
modules = case Component
comp of
CLib Library
lib -> Library -> [ModuleName]
explicitLibModules Library
lib
CExe Executable
exe -> Executable -> [ModuleName]
exeModules Executable
exe
CTest TestSuite
test ->
case TestSuite -> TestSuiteInterface
testInterface TestSuite
test of
TestSuiteExeV10 Version
_ FilePath
_ -> []
TestSuiteLibV09 Version
_ ModuleName
modName -> [ModuleName
modName]
TestSuiteUnsupported TestType
_ -> []
CBench Benchmark
bench -> Benchmark -> [ModuleName]
benchmarkModules Benchmark
bench
CFLib ForeignLib
flib -> ForeignLib -> [ModuleName]
foreignLibModules ForeignLib
flib
sourceFiles :: [FilePath]
sourceFiles = case Component
comp of
CLib Library
_ -> []
CExe Executable
exe -> [Executable -> FilePath
modulePath Executable
exe]
CTest TestSuite
test ->
case TestSuite -> TestSuiteInterface
testInterface TestSuite
test of
TestSuiteExeV10 Version
_ FilePath
fp -> [FilePath
fp]
TestSuiteLibV09 Version
_ ModuleName
_ -> []
TestSuiteUnsupported TestType
_ -> []
CBench Benchmark
bench -> case Benchmark -> BenchmarkInterface
benchmarkInterface Benchmark
bench of
BenchmarkExeV10 Version
_ FilePath
fp -> [FilePath
fp]
BenchmarkUnsupported BenchmarkType
_ -> []
CFLib ForeignLib
_ -> []
cabalFile :: [(FilePath, Json)]
cabalFile
| Just FilePath
fp <- LocalBuildInfo -> Maybe FilePath
pkgDescrFile LocalBuildInfo
lbi = [(FilePath
"cabal-file", FilePath -> Json
JsonString FilePath
fp)]
| Bool
otherwise = []
getCompilerArgs
:: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([String], [String])
getCompilerArgs :: BuildInfo
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([FilePath], [FilePath])
getCompilerArgs BuildInfo
bi LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi =
case Compiler -> CompilerFlavor
compilerFlavor (Compiler -> CompilerFlavor) -> Compiler -> CompilerFlavor
forall a b. (a -> b) -> a -> b
$ LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi of
CompilerFlavor
GHC -> ([], [FilePath]
ghc)
CompilerFlavor
GHCJS -> ([], [FilePath]
ghc)
CompilerFlavor
c ->
( [FilePath
"ShowBuildInfo.getCompilerArgs: Don't know how to get build "
FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
" arguments for compiler " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ CompilerFlavor -> FilePath
forall a. Show a => a -> FilePath
show CompilerFlavor
c]
, [])
where
ghc :: [FilePath]
ghc = Compiler -> Platform -> GhcOptions -> [FilePath]
GHC.renderGhcOptions (LocalBuildInfo -> Compiler
compiler LocalBuildInfo
lbi) (LocalBuildInfo -> Platform
hostPlatform LocalBuildInfo
lbi) GhcOptions
baseOpts
where
baseOpts :: GhcOptions
baseOpts = Verbosity
-> LocalBuildInfo
-> BuildInfo
-> ComponentLocalBuildInfo
-> FilePath
-> GhcOptions
GHC.componentGhcOptions Verbosity
normal LocalBuildInfo
lbi BuildInfo
bi ComponentLocalBuildInfo
clbi (LocalBuildInfo -> FilePath
buildDir LocalBuildInfo
lbi)