1+ {-# LANGUAGE BangPatterns #-}
12{-# LANGUAGE CPP #-}
23{-# LANGUAGE DataKinds #-}
34{-# LANGUAGE GADTs #-}
@@ -118,10 +119,12 @@ import qualified Data.List.NonEmpty as NE
118119import Control.Concurrent.STM (TVar , atomically , modifyTVar )
119120import Control.Exception (ErrorCall , Handler (.. ), SomeAsyncException , assert , catches , onException )
120121import Data.IORef (newIORef , readIORef , writeIORef )
122+ import GHC.Clock (getMonotonicTime )
121123import System.Directory (canonicalizePath , createDirectoryIfMissing , doesDirectoryExist , listDirectory )
122124import System.FilePath (dropDrive , normalise , takeDirectory , (<.>) , (</>) )
123125import System.IO (Handle , IOMode (AppendMode ), withFile )
124126import System.Semaphore (SemaphoreIdentifier )
127+ import Text.Printf (printf )
125128
126129import GHC.Stack
127130import Web.Browser (openBrowser )
@@ -189,7 +192,10 @@ buildAndRegisterUnpackedPackage
189192 verbosity
190193 distDirLayout@ DistDirLayout {distTempDirectory}
191194 maybe_semaphore
192- buildTimeSettings@ BuildTimeSettings {buildSettingKeepTempFiles}
195+ buildTimeSettings@ BuildTimeSettings
196+ { buildSettingKeepTempFiles
197+ , buildSettingBuildTimings
198+ }
193199 registerLock
194200 cacheLock
195201 pkgshared@ ElaboratedSharedConfig
@@ -205,7 +211,7 @@ buildAndRegisterUnpackedPackage
205211 delegate = do
206212 -- Configure phase
207213 mbLBI <-
208- delegate $
214+ timedDelegate $
209215 PBConfigurePhase $
210216 annotateFailure mlogFile ConfigureFailed $
211217 setup
@@ -216,7 +222,7 @@ buildAndRegisterUnpackedPackage
216222 (InLibraryArgs $ InLibraryConfigureArgs pkgshared rpkg ipiTVar)
217223
218224 -- Build phase
219- delegate $
225+ timedDelegate $
220226 PBBuildPhase $
221227 annotateFailure mlogFile BuildFailed $ do
222228 setup
@@ -228,7 +234,7 @@ buildAndRegisterUnpackedPackage
228234
229235 -- Haddock phase
230236 whenHaddock $
231- delegate $
237+ timedDelegate $
232238 PBHaddockPhase $
233239 annotateFailure mlogFile HaddocksFailed $ do
234240 setup
@@ -244,7 +250,7 @@ buildAndRegisterUnpackedPackage
244250 -- the installed package id is, not the build system.
245251 ipkg0 <- generateInstalledPackageInfo mbLBI
246252 return ipkg0{Installed. installedUnitId = uid}
247- delegate $
253+ timedDelegate $
248254 PBInstallPhase
249255 { runCopy = \ destdir ->
250256 annotateFailure mlogFile InstallFailed $
@@ -273,7 +279,7 @@ buildAndRegisterUnpackedPackage
273279
274280 -- Test phase
275281 whenTest $
276- delegate $
282+ timedDelegate $
277283 PBTestPhase $
278284 annotateFailure mlogFile TestsFailed $
279285 setup
@@ -285,7 +291,7 @@ buildAndRegisterUnpackedPackage
285291
286292 -- Bench phase
287293 whenBench $
288- delegate $
294+ timedDelegate $
289295 PBBenchPhase $
290296 annotateFailure mlogFile BenchFailed $
291297 setup
@@ -297,7 +303,7 @@ buildAndRegisterUnpackedPackage
297303
298304 -- Repl phase
299305 whenRepl $
300- delegate $
306+ timedDelegate $
301307 PBReplPhase $
302308 annotateFailure mlogFile ReplFailed $
303309 setupInteractive
@@ -311,6 +317,33 @@ buildAndRegisterUnpackedPackage
311317 where
312318 uid = installedUnitId rpkg
313319
320+ timedDelegate :: forall r . PackageBuildingPhase r -> IO r
321+ timedDelegate phase
322+ | buildSettingBuildTimings = do
323+ t0 <- getMonotonicTime
324+ let
325+ printTiming :: String -> IO ()
326+ printTiming suffix = do
327+ t1 <- getMonotonicTime
328+ let
329+ elapsed = t1 - t0
330+ pkgstr = prettyShow (packageId rpkg)
331+ msg =
332+ unwords
333+ [ " [build-timings]"
334+ , buildPhaseName phase
335+ , pkgstr
336+ , -- Print milliseconds (3 decimal places)
337+ printf " %.3fs" elapsed
338+ , suffix
339+ ]
340+ notice verbosity msg
341+ r <- delegate phase `onException` printTiming " (failed)"
342+ ! _ <- evaluate r
343+ printTiming " "
344+ return r
345+ | otherwise = delegate phase
346+
314347 comp_par_strat = case maybe_semaphore of
315348 Just sem_ident -> Cabal. toFlag sem_ident
316349 _ -> Cabal. NoFlag
@@ -1014,6 +1047,16 @@ annotateFailure mlogFile annotate action =
10141047-- * Other Utils
10151048--------------------------------------------------------------------------------
10161049
1050+ -- | Display name for each build phase, used in timing output.
1051+ buildPhaseName :: PackageBuildingPhase r -> String
1052+ buildPhaseName PBConfigurePhase {} = " configure"
1053+ buildPhaseName PBBuildPhase {} = " build"
1054+ buildPhaseName PBHaddockPhase {} = " haddock"
1055+ buildPhaseName PBReplPhase {} = " repl"
1056+ buildPhaseName PBInstallPhase {} = " install"
1057+ buildPhaseName PBTestPhase {} = " test"
1058+ buildPhaseName PBBenchPhase {} = " bench"
1059+
10171060hasValidHaddockTargets :: ElaboratedConfiguredPackage -> Bool
10181061hasValidHaddockTargets ElaboratedConfiguredPackage {.. }
10191062 | not elabBuildHaddocks = False
0 commit comments