Skip to content

Commit 446af09

Browse files
committed
Remove Show-build-info command and generate buildinfo on build
Removes 'show-build-info' command from 'lib:Cabal' and replaces it by generating build-info whenever a build happens. Add flag '--dump-buildinfo' to signal the build step to dump build information for the package/component we are currently building.
1 parent 188862a commit 446af09

File tree

13 files changed

+98
-160
lines changed

13 files changed

+98
-160
lines changed

Cabal/Cabal.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ library
201201
Distribution.Types.ComponentInclude
202202
Distribution.Types.ConfVar
203203
Distribution.Types.Dependency
204+
Distribution.Types.DumpBuildInfo
204205
Distribution.Types.ExeDependency
205206
Distribution.Types.LegacyExeDependency
206207
Distribution.Types.PkgconfigDependency

Cabal/src/Distribution/Simple.hs

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ import Data.List (unionBy, (\\))
107107

108108
import Distribution.PackageDescription.Parsec
109109

110-
import qualified Data.Text.IO as T
111-
112110
-- | A simple implementation of @main@ for a Cabal setup script.
113111
-- It reads the package description file using IO, and performs the
114112
-- action specified on the command line.
@@ -179,7 +177,6 @@ defaultMainHelper hooks args = topHandler $ do
179177
[configureCommand progs `commandAddAction`
180178
\fs as -> configureAction hooks fs as >> return ()
181179
,buildCommand progs `commandAddAction` buildAction hooks
182-
,showBuildInfoCommand progs `commandAddAction` showBuildInfoAction hooks
183180
,replCommand progs `commandAddAction` replAction hooks
184181
,installCommand `commandAddAction` installAction hooks
185182
,copyCommand `commandAddAction` copyAction hooks
@@ -264,36 +261,6 @@ buildAction hooks flags args = do
264261
(return lbi { withPrograms = progs })
265262
hooks flags' { buildArgs = args } args
266263

267-
showBuildInfoAction :: UserHooks -> ShowBuildInfoFlags -> Args -> IO ()
268-
showBuildInfoAction hooks flags args = do
269-
let buildFlags = buildInfoBuildFlags flags
270-
distPref <- findDistPrefOrDefault (buildDistPref buildFlags)
271-
let verbosity = fromFlag $ buildVerbosity buildFlags
272-
lbi <- getBuildConfig hooks verbosity distPref
273-
let buildFlags' =
274-
buildFlags { buildDistPref = toFlag distPref
275-
, buildCabalFilePath = maybeToFlag (cabalFilePath lbi)
276-
}
277-
278-
progs <- reconfigurePrograms verbosity
279-
(buildProgramPaths buildFlags')
280-
(buildProgramArgs buildFlags')
281-
(withPrograms lbi)
282-
283-
pbi <- preBuild hooks args buildFlags'
284-
let lbi' = lbi { withPrograms = progs }
285-
pkg_descr0 = localPkgDescr lbi'
286-
pkg_descr = updatePackageDescription pbi pkg_descr0
287-
-- TODO: Somehow don't ignore build hook?
288-
289-
buildInfoText <- showBuildInfo pkg_descr lbi' flags
290-
291-
case buildInfoOutputFile flags of
292-
Nothing -> T.putStr buildInfoText
293-
Just fp -> T.writeFile fp buildInfoText
294-
295-
postBuild hooks args buildFlags' pkg_descr lbi'
296-
297264
replAction :: UserHooks -> ReplFlags -> Args -> IO ()
298265
replAction hooks flags args = do
299266
distPref <- findDistPrefOrDefault (replDistPref flags)

Cabal/src/Distribution/Simple/Build.hs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
--
2020

2121
module Distribution.Simple.Build (
22-
build, showBuildInfo, repl,
22+
build, repl,
2323
startInterpreter,
2424

2525
initialBuildSteps,
@@ -90,7 +90,7 @@ import Control.Monad
9090
import qualified Data.Set as Set
9191
import System.FilePath ( (</>), (<.>), takeDirectory )
9292
import System.Directory ( getCurrentDirectory )
93-
import qualified Data.Text as Text
93+
import qualified Data.Text.IO as Text
9494

9595
-- -----------------------------------------------------------------------------
9696
-- |Build the libraries and executables in this package.
@@ -128,32 +128,27 @@ build pkg_descr lbi flags suffixes = do
128128
mb_ipi <- buildComponent verbosity (buildNumJobs flags) pkg_descr
129129
lbi' suffixes comp clbi distPref
130130
return (maybe index (Index.insert `flip` index) mb_ipi)
131+
132+
when shouldDumpBuildInfo $ do
133+
-- Changing this line might break consumers of the dumped build info.
134+
-- Announce changes on mailing lists!
135+
let activeTargets = allTargetsInBuildOrder' pkg_descr lbi
136+
info verbosity $ "Dump build information for: "
137+
++ intercalate ", "
138+
(map (showComponentName . componentLocalName . targetCLBI)
139+
activeTargets)
140+
pwd <- getCurrentDirectory
141+
let (warns, json) = mkBuildInfo pwd pkg_descr lbi flags activeTargets
142+
buildInfoText = renderJson json mempty
143+
unless (null warns) $
144+
warn verbosity $ "Encountered warnings while dumping build-info:\n"
145+
++ unlines warns
146+
Text.writeFile (buildInfoPref distPref) buildInfoText
131147
return ()
132148
where
133149
distPref = fromFlag (buildDistPref flags)
134150
verbosity = fromFlag (buildVerbosity flags)
135-
136-
137-
showBuildInfo :: PackageDescription -- ^ Mostly information from the .cabal file
138-
-> LocalBuildInfo -- ^ Configuration information
139-
-> ShowBuildInfoFlags -- ^ Flags that the user passed to build
140-
-> IO Text.Text
141-
showBuildInfo pkg_descr lbi flags = do
142-
let buildFlags = buildInfoBuildFlags flags
143-
verbosity = fromFlag (buildVerbosity buildFlags)
144-
targets <- readTargetInfos verbosity pkg_descr lbi (buildArgs buildFlags)
145-
pwd <- getCurrentDirectory
146-
let targetsToBuild = neededTargetsInBuildOrder' pkg_descr lbi (map nodeKey targets)
147-
result
148-
| fromFlag (buildInfoComponentsOnly flags) =
149-
let components = map (mkComponentInfo pwd pkg_descr lbi . targetCLBI)
150-
targetsToBuild
151-
in Text.unlines $ map (flip renderJson mempty) components
152-
| otherwise =
153-
let json = mkBuildInfo pwd pkg_descr lbi buildFlags targetsToBuild
154-
in renderJson json mempty
155-
return result
156-
151+
shouldDumpBuildInfo = fromFlag (configDumpBuildInfo (configFlags lbi)) == DumpBuildInfo
157152

158153
repl :: PackageDescription -- ^ Mostly information from the .cabal file
159154
-> LocalBuildInfo -- ^ Configuration information

Cabal/src/Distribution/Simple/BuildPaths.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
module Distribution.Simple.BuildPaths (
1717
defaultDistPref, srcPref,
18-
haddockDirName, hscolourPref, haddockPref,
18+
buildInfoPref, haddockDirName, hscolourPref, haddockPref,
1919
autogenPackageModulesDir,
2020
autogenComponentModulesDir,
2121

@@ -67,6 +67,10 @@ srcPref distPref = distPref </> "src"
6767
hscolourPref :: HaddockTarget -> FilePath -> PackageDescription -> FilePath
6868
hscolourPref = haddockPref
6969

70+
-- | Build info json file, generated in every build
71+
buildInfoPref :: FilePath -> FilePath
72+
buildInfoPref distPref = distPref </> "build-info.json"
73+
7074
-- | This is the name of the directory in which the generated haddocks
7175
-- should be stored. It does not include the @<dist>/doc/html@ prefix.
7276
haddockDirName :: HaddockTarget -> PackageDescription -> FilePath

Cabal/src/Distribution/Simple/Setup.hs

Lines changed: 14 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ module Distribution.Simple.Setup (
4545
HaddockFlags(..), emptyHaddockFlags, defaultHaddockFlags, haddockCommand,
4646
HscolourFlags(..), emptyHscolourFlags, defaultHscolourFlags, hscolourCommand,
4747
BuildFlags(..), emptyBuildFlags, defaultBuildFlags, buildCommand,
48-
ShowBuildInfoFlags(..), defaultShowBuildFlags, showBuildInfoCommand,
48+
DumpBuildInfo(..),
4949
ReplFlags(..), defaultReplFlags, replCommand,
5050
CleanFlags(..), emptyCleanFlags, defaultCleanFlags, cleanCommand,
5151
RegisterFlags(..), emptyRegisterFlags, defaultRegisterFlags, registerCommand,
@@ -98,6 +98,7 @@ import Distribution.Simple.InstallDirs
9898
import Distribution.Verbosity
9999
import Distribution.Utils.NubList
100100
import Distribution.Types.ComponentId
101+
import Distribution.Types.DumpBuildInfo
101102
import Distribution.Types.GivenComponent
102103
import Distribution.Types.Module
103104
import Distribution.Types.PackageVersionConstraint
@@ -273,6 +274,11 @@ data ConfigFlags = ConfigFlags {
273274
configUseResponseFiles :: Flag Bool,
274275
-- ^ Whether to use response files at all. They're used for such tools
275276
-- as haddock, or ld.
277+
configDumpBuildInfo :: Flag DumpBuildInfo,
278+
-- ^ Should we dump available build information on build?
279+
-- After a successful build, tooling can parse these files and use them
280+
-- to compile the source files themselves. Helpful for IDEs such as
281+
-- Haskell Language Server
276282
configAllowDependingOnPrivateLibs :: Flag Bool
277283
-- ^ Allow depending on private sublibraries. This is used by external
278284
-- tools (like cabal-install) so they can add multiple-public-libraries
@@ -388,6 +394,7 @@ defaultConfigFlags progDb = emptyConfigFlags {
388394
configFlagError = NoFlag,
389395
configRelocatable = Flag False,
390396
configDebugInfo = Flag NoDebugInfo,
397+
configDumpBuildInfo = Flag NoDumpBuildInfo,
391398
configUseResponseFiles = NoFlag
392399
}
393400

@@ -706,6 +713,12 @@ configureOptions showOrParseArgs =
706713
(\v flags -> flags { configUseResponseFiles = v })
707714
(boolOpt' ([], ["disable-response-files"]) ([], []))
708715

716+
, option "" ["dump-buildinfo"]
717+
"enable dumping build information during building the project"
718+
configDumpBuildInfo
719+
(\v flags -> flags { configDumpBuildInfo = v })
720+
(noArg (Flag DumpBuildInfo) )
721+
709722
,option "" ["allow-depending-on-private-libs"]
710723
( "Allow depending on private libraries. "
711724
++ "If set, the library visibility check MUST be done externally." )
@@ -2147,88 +2160,6 @@ optionNumJobs get set =
21472160
| otherwise -> Right (Just n)
21482161
_ -> Left "The jobs value should be a number or '$ncpus'"
21492162

2150-
2151-
-- ------------------------------------------------------------
2152-
-- * show-build-info command flags
2153-
-- ------------------------------------------------------------
2154-
2155-
data ShowBuildInfoFlags = ShowBuildInfoFlags
2156-
{ buildInfoBuildFlags :: BuildFlags
2157-
, buildInfoOutputFile :: Maybe FilePath
2158-
, buildInfoComponentsOnly :: Flag Bool
2159-
-- ^ If 'True' then only print components, each separated by a newline
2160-
} deriving (Show, Typeable)
2161-
2162-
defaultShowBuildFlags :: ShowBuildInfoFlags
2163-
defaultShowBuildFlags =
2164-
ShowBuildInfoFlags
2165-
{ buildInfoBuildFlags = defaultBuildFlags
2166-
, buildInfoOutputFile = Nothing
2167-
, buildInfoComponentsOnly = Flag False
2168-
}
2169-
2170-
showBuildInfoCommand :: ProgramDb -> CommandUI ShowBuildInfoFlags
2171-
showBuildInfoCommand progDb = CommandUI
2172-
{ commandName = "show-build-info"
2173-
, commandSynopsis = "Emit details about how a package would be built."
2174-
, commandDescription = Just $ \_ -> wrapText $
2175-
"Components encompass executables, tests, and benchmarks.\n"
2176-
++ "\n"
2177-
++ "Affected by configuration options, see `configure`.\n"
2178-
, commandNotes = Just $ \pname ->
2179-
"Examples:\n"
2180-
++ " " ++ pname ++ " show-build-info "
2181-
++ " All the components in the package\n"
2182-
++ " " ++ pname ++ " show-build-info foo "
2183-
++ " A component (i.e. lib, exe, test suite)\n\n"
2184-
++ programFlagsDescription progDb
2185-
--TODO: re-enable once we have support for module/file targets
2186-
-- ++ " " ++ pname ++ " show-build-info Foo.Bar "
2187-
-- ++ " A module\n"
2188-
-- ++ " " ++ pname ++ " show-build-info Foo/Bar.hs"
2189-
-- ++ " A file\n\n"
2190-
-- ++ "If a target is ambiguous it can be qualified with the component "
2191-
-- ++ "name, e.g.\n"
2192-
-- ++ " " ++ pname ++ " show-build-info foo:Foo.Bar\n"
2193-
-- ++ " " ++ pname ++ " show-build-info testsuite1:Foo/Bar.hs\n"
2194-
, commandUsage = usageAlternatives "show-build-info" $
2195-
[ "[FLAGS]"
2196-
, "COMPONENTS [FLAGS]"
2197-
]
2198-
, commandDefaultFlags = defaultShowBuildFlags
2199-
, commandOptions = \showOrParseArgs ->
2200-
parseBuildFlagsForShowBuildInfoFlags showOrParseArgs progDb
2201-
++
2202-
[ option [] ["buildinfo-json-output"]
2203-
"Write the result to the given file instead of stdout"
2204-
buildInfoOutputFile (\v flags -> flags { buildInfoOutputFile = v })
2205-
(reqArg' "FILE" Just (maybe [] pure))
2206-
, option [] ["buildinfo-components-only"]
2207-
"Print out only the component info, each separated by a newline"
2208-
buildInfoComponentsOnly (\v flags -> flags { buildInfoComponentsOnly = v})
2209-
trueArg
2210-
]
2211-
2212-
}
2213-
2214-
parseBuildFlagsForShowBuildInfoFlags :: ShowOrParseArgs -> ProgramDb -> [OptionField ShowBuildInfoFlags]
2215-
parseBuildFlagsForShowBuildInfoFlags showOrParseArgs progDb =
2216-
map
2217-
(liftOption
2218-
buildInfoBuildFlags
2219-
(\bf flags -> flags { buildInfoBuildFlags = bf } )
2220-
)
2221-
buildFlags
2222-
where
2223-
buildFlags = buildOptions progDb showOrParseArgs
2224-
++
2225-
[ optionVerbosity
2226-
buildVerbosity (\v flags -> flags { buildVerbosity = v })
2227-
2228-
, optionDistPref
2229-
buildDistPref (\d flags -> flags { buildDistPref = d }) showOrParseArgs
2230-
]
2231-
22322163
-- ------------------------------------------------------------
22332164
-- * Other Utils
22342165
-- ------------------------------------------------------------

Cabal/src/Distribution/Simple/ShowBuildInfo.hs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module Distribution.Simple.ShowBuildInfo
6060
( mkBuildInfo, mkBuildInfo', mkCompilerInfo, mkComponentInfo ) where
6161

6262
import qualified Data.Text as T
63+
import System.FilePath
6364

6465
import Distribution.Compat.Prelude
6566
import Prelude ()
@@ -88,11 +89,16 @@ mkBuildInfo
8889
-> LocalBuildInfo -- ^ Configuration information
8990
-> BuildFlags -- ^ Flags that the user passed to build
9091
-> [TargetInfo]
91-
-> Json
92+
-> ([String], Json) -- ^ Json representation of buildinfo alongside generated warnings
9293
mkBuildInfo wdir pkg_descr lbi _flags targetsToBuild =
93-
JsonObject $
94-
mkBuildInfo' (mkCompilerInfo (withPrograms lbi) (compiler lbi))
95-
(map (mkComponentInfo wdir pkg_descr lbi . targetCLBI) targetsToBuild)
94+
( warnings
95+
, JsonObject $ mkBuildInfo' (mkCompilerInfo (withPrograms lbi) (compiler lbi))
96+
componentInfos
97+
)
98+
where
99+
componentInfosWithWarnings = (map (mkComponentInfo wdir pkg_descr lbi . targetCLBI) targetsToBuild)
100+
componentInfos = map snd componentInfosWithWarnings
101+
warnings = concatMap fst componentInfosWithWarnings
96102

97103
-- | A variant of 'mkBuildInfo' if you need to call 'mkCompilerInfo' and
98104
-- 'mkComponentInfo' yourself.
@@ -124,20 +130,22 @@ mkCompilerInfo programDb cmplr = JsonObject
124130
flavorToProgram JHC = Just jhcProgram
125131
flavorToProgram _ = Nothing
126132

127-
mkComponentInfo :: FilePath -> PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> Json
128-
mkComponentInfo wdir pkg_descr lbi clbi = JsonObject $
133+
mkComponentInfo :: FilePath -> PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> ([String], Json)
134+
mkComponentInfo wdir pkg_descr lbi clbi = (warnings, JsonObject $
129135
[ "type" .= JsonString compType
130136
, "name" .= JsonString (T.pack $ prettyShow name)
131137
, "unit-id" .= JsonString (T.pack $ prettyShow $ componentUnitId clbi)
132-
, "compiler-args" .= JsonArray (map JsonString $ getCompilerArgs bi lbi clbi)
138+
, "compiler-args" .= JsonArray (map JsonString compilerArgs)
133139
, "modules" .= JsonArray (map (JsonString . T.pack . display) modules)
134140
, "src-files" .= JsonArray (map (JsonString . T.pack) sourceFiles)
135141
, "hs-src-dirs" .= JsonArray (map (JsonString . T.pack . prettyShow) $ hsSourceDirs bi)
136-
, "src-dir" .= JsonString (T.pack wdir)
137-
] <> cabalFile
142+
, "src-dir" .= JsonString (T.pack $ addTrailingPathSeparator wdir)
143+
] <> cabalFile)
138144
where
145+
(warnings, compilerArgs) = getCompilerArgs bi lbi clbi
139146
name = componentLocalName clbi
140147
bi = componentBuildInfo comp
148+
-- If this error happens, a cabal invariant has been violated
141149
comp = fromMaybe (error $ "mkBuildInfo: no component " ++ prettyShow name) $ lookupComponent pkg_descr name
142150
compType = case comp of
143151
CLib _ -> "lib"
@@ -178,13 +186,15 @@ getCompilerArgs
178186
:: BuildInfo
179187
-> LocalBuildInfo
180188
-> ComponentLocalBuildInfo
181-
-> [T.Text]
189+
-> ([String], [T.Text])
182190
getCompilerArgs bi lbi clbi =
183191
case compilerFlavor $ compiler lbi of
184-
GHC -> ghc
185-
GHCJS -> ghc
186-
c -> error $ "ShowBuildInfo.getCompilerArgs: Don't know how to get "++
187-
"build arguments for compiler "++show c
192+
GHC -> ([], ghc)
193+
GHCJS -> ([], ghc)
194+
c ->
195+
( ["ShowBuildInfo.getCompilerArgs: Don't know how to get build "
196+
++ " arguments for compiler " ++ show c]
197+
, [])
188198
where
189199
-- This is absolutely awful
190200
ghc = T.pack <$>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{-# LANGUAGE DeriveDataTypeable #-}
2+
{-# LANGUAGE DeriveGeneric #-}
3+
module Distribution.Types.DumpBuildInfo
4+
( DumpBuildInfo(..)
5+
) where
6+
7+
import Distribution.Compat.Prelude
8+
9+
data DumpBuildInfo
10+
= NoDumpBuildInfo
11+
| DumpBuildInfo
12+
deriving (Read, Show, Eq, Ord, Enum, Bounded, Generic, Typeable)
13+
14+
instance Binary DumpBuildInfo
15+
instance Structured DumpBuildInfo

cabal-install/src/Distribution/Client/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ instance Semigroup SavedConfig where
408408
configFlagError = combine configFlagError,
409409
configRelocatable = combine configRelocatable,
410410
configUseResponseFiles = combine configUseResponseFiles,
411+
configDumpBuildInfo = combine configDumpBuildInfo,
411412
configAllowDependingOnPrivateLibs =
412413
combine configAllowDependingOnPrivateLibs
413414
}

0 commit comments

Comments
 (0)