1 {-# LANGUAGE OverloadedStrings #-}
4 -- This module defines a simple JSON-based format for exporting basic
5 -- information about a Cabal package and the compiler configuration Cabal
6 -- would use to build it. This can be produced with the
7 -- @cabal build --enable-build-info@ command.
10 -- This format is intended for consumption by external tooling and should
11 -- therefore be rather stable. Moreover, this allows tooling users to avoid
12 -- linking against Cabal. This is an important advantage as direct API usage
13 -- tends to be rather fragile in the presence of user-initiated upgrades of
16 -- Below is an example of the output this module produces,
19 -- { "cabal-lib-version": "1.23.0.0",
22 -- "compiler-id": "ghc-7.10.2",
23 -- "path": "/usr/bin/ghc",
27 -- "name": "lib:Cabal",
29 -- ["-O", "-XHaskell98", "-Wall",
30 -- "-package-id", "parallel-3.2.0.6-b79c38c5c25fff77f3ea7271851879eb"]
31 -- "modules": ["Project.ModA", "Project.ModB", "Paths_project"],
33 -- "src-dirs": ["src"]
39 -- The output format needs to be validated against 'doc/json-schemas/build-info.schema.json'.
40 -- If the format changes, update the schema as well!
42 -- The @cabal-lib-version@ property provides the version of the Cabal library
43 -- which generated the output. The @compiler@ property gives some basic
44 -- information about the compiler Cabal would use to compile the package.
46 -- The @components@ property gives a list of the Cabal 'Component's defined by
47 -- the package. Each has,
49 -- * @type@: the type of the component (one of @lib@, @exe@,
50 -- @test@, @bench@, or @flib@)
51 -- * @name@: a string serving to uniquely identify the component within the
53 -- * @compiler-args@: the command-line arguments Cabal would pass to the
54 -- compiler to compile the component
55 -- * @modules@: the modules belonging to the component
56 -- * @src-dirs@: a list of directories where the modules might be found
57 -- * @src-files@: any other Haskell sources needed by the component
59 -- Note: At the moment this is only supported when using the GHC compiler.
60 module Distribution
.Simple
.ShowBuildInfo
67 import System
.FilePath
69 import Distribution
.Compat
.Prelude
72 import qualified Distribution
.Simple
.GHC
as GHC
73 import qualified Distribution
.Simple
.Program
.GHC
as GHC
75 import Distribution
.Compiler
76 import Distribution
.PackageDescription
77 import Distribution
.Pretty
78 import Distribution
.Simple
.Compiler
(Compiler
, compilerFlavor
, showCompilerId
)
79 import Distribution
.Simple
.Program
80 import Distribution
.Simple
.Setup
.Build
(BuildFlags
)
81 import Distribution
.Simple
.Utils
(cabalVersion
)
82 import Distribution
.Text
83 import Distribution
.Types
.Component
84 import Distribution
.Types
.ComponentLocalBuildInfo
85 import Distribution
.Types
.LocalBuildInfo
86 import Distribution
.Types
.TargetInfo
87 import Distribution
.Utils
.Json
88 import Distribution
.Verbosity
90 -- | Construct a JSON document describing the build information for a
94 -- ^ The source directory of the package
96 -- ^ Mostly information from the .cabal file
98 -- ^ Configuration information
100 -- ^ Flags that the user passed to build
101 -> (ConfiguredProgram
, Compiler
)
102 -- ^ Compiler information.
103 -- Needs to be passed explicitly, as we can't extract that information here
104 -- without some partial function.
107 -- ^ Json representation of buildinfo alongside generated warnings
108 mkBuildInfo wdir pkg_descr lbi _flags compilerInfo targetsToBuild
= (warnings
, JsonObject buildInfoFields
)
110 buildInfoFields
= mkBuildInfo
' (uncurry mkCompilerInfo compilerInfo
) componentInfos
111 componentInfosWithWarnings
= map (mkComponentInfo wdir pkg_descr lbi
. targetCLBI
) targetsToBuild
112 componentInfos
= map snd componentInfosWithWarnings
113 warnings
= concatMap fst componentInfosWithWarnings
115 -- | A variant of 'mkBuildInfo' if you need to call 'mkCompilerInfo' and
116 -- 'mkComponentInfo' yourself.
118 -- If you change the format or any name in the output json, don't forget to update
119 -- the schema at @\/doc\/json-schemas\/build-info.schema.json@ and the docs of
120 -- @--enable-build-info@\/@--disable-build-info@.
123 -- ^ The 'Json' from 'mkCompilerInfo'
125 -- ^ The 'Json' from 'mkComponentInfo'
127 mkBuildInfo
' compilerInfo componentInfos
=
128 [ "cabal-lib-version" .= JsonString
(display cabalVersion
)
129 , "compiler" .= compilerInfo
130 , "components" .= JsonArray componentInfos
133 mkCompilerInfo
:: ConfiguredProgram
-> Compiler
-> Json
134 mkCompilerInfo compilerProgram compilerInfo
=
136 [ "flavour" .= JsonString
(prettyShow
$ compilerFlavor compilerInfo
)
137 , "compiler-id" .= JsonString
(showCompilerId compilerInfo
)
138 , "path" .= JsonString
(programPath compilerProgram
)
141 mkComponentInfo
:: FilePath -> PackageDescription
-> LocalBuildInfo
-> ComponentLocalBuildInfo
-> ([String], Json
)
142 mkComponentInfo wdir pkg_descr lbi clbi
=
145 [ "type" .= JsonString compType
146 , "name" .= JsonString
(prettyShow name
)
147 , "unit-id" .= JsonString
(prettyShow
$ componentUnitId clbi
)
148 , "compiler-args" .= JsonArray
(map JsonString compilerArgs
)
149 , "modules" .= JsonArray
(map (JsonString
. display
) modules
)
150 , "src-files" .= JsonArray
(map JsonString sourceFiles
)
151 , "hs-src-dirs" .= JsonArray
(map (JsonString
. prettyShow
) $ hsSourceDirs bi
)
152 , "src-dir" .= JsonString
(addTrailingPathSeparator wdir
)
157 (warnings
, compilerArgs
) = getCompilerArgs bi lbi clbi
158 name
= componentLocalName clbi
159 bi
= componentBuildInfo comp
160 -- If this error happens, a cabal invariant has been violated
161 comp
= fromMaybe (error $ "mkBuildInfo: no component " ++ prettyShow name
) $ lookupComponent pkg_descr name
162 compType
= case comp
of
168 modules
= case comp
of
169 CLib lib
-> explicitLibModules lib
170 CExe exe
-> exeModules exe
172 case testInterface test
of
173 TestSuiteExeV10 _ _
-> []
174 TestSuiteLibV09 _ modName
-> [modName
]
175 TestSuiteUnsupported _
-> []
176 CBench bench
-> benchmarkModules bench
177 CFLib flib
-> foreignLibModules flib
178 sourceFiles
= case comp
of
180 CExe exe
-> [modulePath exe
]
182 case testInterface test
of
183 TestSuiteExeV10 _ fp
-> [fp
]
184 TestSuiteLibV09 _ _
-> []
185 TestSuiteUnsupported _
-> []
186 CBench bench
-> case benchmarkInterface bench
of
187 BenchmarkExeV10 _ fp
-> [fp
]
188 BenchmarkUnsupported _
-> []
191 | Just fp
<- pkgDescrFile lbi
= [("cabal-file", JsonString fp
)]
194 -- | Get the command-line arguments that would be passed
195 -- to the compiler to build the given component.
199 -> ComponentLocalBuildInfo
200 -> ([String], [String])
201 getCompilerArgs bi lbi clbi
=
202 case compilerFlavor
$ compiler lbi
of
207 [ "ShowBuildInfo.getCompilerArgs: Don't know how to get build "
208 ++ " arguments for compiler "
214 -- This is absolutely awful
215 ghc
= GHC
.renderGhcOptions
(compiler lbi
) (hostPlatform lbi
) baseOpts
217 baseOpts
= GHC
.componentGhcOptions normal lbi bi clbi
(buildDir lbi
)