diff --git a/cabal-install/Distribution/Client/ProjectBuilding.hs b/cabal-install/Distribution/Client/ProjectBuilding.hs
index e70923660e772b411280b00c12f12530b5932706..ca8dce760fde94d4faac924b4edc340160f35592 100644
--- a/cabal-install/Distribution/Client/ProjectBuilding.hs
+++ b/cabal-install/Distribution/Client/ProjectBuilding.hs
@@ -18,6 +18,7 @@ module Distribution.Client.ProjectBuilding (
     BuildOutcomes,
     BuildResult(..),
     BuildFailure(..),
+    BuildFailureReason(..),
     rebuildTargets
   ) where
 
@@ -507,6 +508,7 @@ checkPackageFileMonitorChanged PackageFileMonitor{..}
                   return $ Right BuildResult {
                     buildResultDocs    = docsResult,
                     buildResultTests   = testsResult,
+                    buildResultLogFile = Nothing,
                     buildResultLibInfo = ipkgs
                   }
                 where
@@ -590,24 +592,33 @@ type BuildOutcome  = Either BuildFailure BuildResult
 data BuildResult = BuildResult {
        buildResultDocs    :: DocsResult,
        buildResultTests   :: TestsResult,
+       buildResultLogFile :: Maybe FilePath,
        buildResultLibInfo :: [InstalledPackageInfo]
      }
   deriving Show
 
 -- | Information arising from the failure to build a single package.
 --
-data BuildFailure = PlanningFailed
-                  | DependentFailed PackageId
-                  | DownloadFailed  SomeException
-                  | UnpackFailed    SomeException
-                  | ConfigureFailed SomeException
-                  | BuildFailed     SomeException
-                  | TestsFailed     SomeException
-                  | InstallFailed   SomeException
+data BuildFailure = BuildFailure {
+       buildFailureLogFile :: Maybe FilePath,
+       buildFailureReason  :: BuildFailureReason
+     }
   deriving (Show, Typeable)
 
 instance Exception BuildFailure
 
+-- | Detail on the reason that a package failed to build.
+--
+data BuildFailureReason = PlanningFailed
+                        | DependentFailed PackageId
+                        | DownloadFailed  SomeException
+                        | UnpackFailed    SomeException
+                        | ConfigureFailed SomeException
+                        | BuildFailed     SomeException
+                        | TestsFailed     SomeException
+                        | InstallFailed   SomeException
+  deriving Show
+
 -- | Build things for real.
 --
 -- It requires the 'BuildStatusMap' gathered by 'rebuildTargetsDryRun'.
@@ -651,7 +662,8 @@ rebuildTargets verbosity
                           installPlan pkgsBuildStatus $ \downloadMap ->
 
       -- For each package in the plan, in dependency order, but in parallel...
-      InstallPlan.execute jobControl keepGoing (DependentFailed . packageId)
+      InstallPlan.execute jobControl keepGoing
+                          (BuildFailure Nothing . DependentFailed . packageId)
                           installPlan $ \pkg ->
         handle (return . Left) $ fmap Right $ --TODO: review exception handling
 
@@ -712,7 +724,7 @@ rebuildTarget verbosity
     unexpectedState = error "rebuildTarget: unexpected package status"
 
     downloadPhase = do
-        downsrcloc <- annotateFailure DownloadFailed $
+        downsrcloc <- annotateFailure (BuildFailure Nothing . DownloadFailed) $
                         waitAsyncPackageDownload verbosity downloadMap pkg
         case downsrcloc of
           DownloadedTarball tarball -> unpackTarballPhase tarball
@@ -875,7 +887,7 @@ unpackPackageTarball :: Verbosity -> FilePath -> FilePath
                      -> IO ()
 unpackPackageTarball verbosity tarball parentdir pkgid pkgTextOverride =
     --TODO: [nice to have] switch to tar package and catch tar exceptions
-    annotateFailure UnpackFailed $ do
+    annotateFailure (BuildFailure Nothing . UnpackFailed) $ do
 
       -- Unpack the tarball
       --
@@ -964,18 +976,18 @@ buildAndInstallUnpackedPackage verbosity
     -- Configure phase
     when isParallelBuild $
       notice verbosity $ "Configuring " ++ display pkgid ++ "..."
-    annotateFailure ConfigureFailed $
+    annotateFailure (BuildFailure mlogFile . ConfigureFailed) $
       setup configureCommand configureFlags
 
     -- Build phase
     when isParallelBuild $
       notice verbosity $ "Building " ++ display pkgid ++ "..."
-    annotateFailure BuildFailed $
+    annotateFailure (BuildFailure mlogFile . BuildFailed) $
       setup buildCommand buildFlags
 
     -- Install phase
     ipkgs <-
-      annotateFailure InstallFailed $ do
+      annotateFailure (BuildFailure mlogFile . InstallFailed) $ do
       --TODO: [required eventually] need to lock installing this ipkig so other processes don't
       -- stomp on our files, since we don't have ABI compat, not safe to replace
 
@@ -1032,6 +1044,7 @@ buildAndInstallUnpackedPackage verbosity
     return BuildResult {
        buildResultDocs    = docsResult,
        buildResultTests   = testsResult,
+       buildResultLogFile = mlogFile,
        buildResultLibInfo = ipkgs
     }
 
@@ -1073,6 +1086,7 @@ buildAndInstallUnpackedPackage verbosity
           (Just (pkgDescription pkg))
           cmd flags []
 
+    mlogFile :: Maybe FilePath
     mlogFile =
       case buildSettingLogFile of
         Nothing        -> Nothing
@@ -1123,7 +1137,7 @@ buildInplaceUnpackedPackage verbosity
         -- Configure phase
         --
         whenReConfigure $ do
-          annotateFailure ConfigureFailed $
+          annotateFailure (BuildFailure Nothing . ConfigureFailed) $
             setup configureCommand configureFlags []
           invalidatePackageRegFileMonitor packageFileMonitor
           updatePackageConfigFileMonitor packageFileMonitor srcdir pkg
@@ -1138,7 +1152,7 @@ buildInplaceUnpackedPackage verbosity
 
         whenRebuild $ do
           timestamp <- beginUpdateFileMonitor
-          annotateFailure BuildFailed $
+          annotateFailure (BuildFailure Nothing . BuildFailed) $
             setup buildCommand buildFlags buildArgs
 
           --TODO: [required eventually] this doesn't track file
@@ -1150,7 +1164,8 @@ buildInplaceUnpackedPackage verbosity
                                         pkg buildStatus
                                         allSrcFiles buildResult
 
-        ipkgs <- whenReRegister $ annotateFailure InstallFailed $ do
+        ipkgs <- whenReRegister $
+                 annotateFailure (BuildFailure Nothing . InstallFailed) $ do
           -- Register locally
           ipkgs <- if pkgRequiresRegistration pkg
             then do
@@ -1225,17 +1240,18 @@ buildInplaceUnpackedPackage verbosity
         -- Repl phase
         --
         whenRepl $
-          annotateFailure BuildFailed $
+          annotateFailure (BuildFailure Nothing . BuildFailed) $
           setup replCommand replFlags replArgs
 
         -- Haddock phase
         whenHaddock $
-          annotateFailure BuildFailed $
+          annotateFailure (BuildFailure Nothing . BuildFailed) $
           setup haddockCommand haddockFlags []
 
         return BuildResult {
           buildResultDocs    = docsResult,
           buildResultTests   = testsResult,
+          buildResultLogFile = Nothing,
           buildResultLibInfo = ipkgs
         }
 
diff --git a/cabal-install/Distribution/Client/ProjectOrchestration.hs b/cabal-install/Distribution/Client/ProjectOrchestration.hs
index bda116df69a96e8d88201a59fc74684e8cb6bcf6..f4f91ef7c2554c951bdca1dceab8492e6e9b176e 100644
--- a/cabal-install/Distribution/Client/ProjectOrchestration.hs
+++ b/cabal-install/Distribution/Client/ProjectOrchestration.hs
@@ -484,19 +484,19 @@ reportBuildFailures plan buildOutcomes
 
   | otherwise
   = case failuresPrimary of
-     [(pkg, reason)] -> die $ renderFailure pkg reason
+     [(pkg, failure)] -> die $ renderFailure pkg (buildFailureReason failure)
      multiple        -> die $ "multiple failures:\n"
-                           ++ unlines
-                                [ renderFailure pkg reason
-                                | (pkg, reason) <- multiple ]
+                            ++ unlines
+                                 [ renderFailure pkg (buildFailureReason failure)
+                                 | (pkg, failure) <- multiple ]
   where
-    failures =  [ (pkgid, reason)
-                | (pkgid, Left reason) <- Map.toList buildOutcomes ]
+    failures =  [ (pkgid, failure)
+                | (pkgid, Left failure) <- Map.toList buildOutcomes ]
 
     failuresPrimary =
-      [ (pkg, reason)
-      | (pkgid, reason) <- failures
-      , case reason of
+      [ (pkg, failure)
+      | (pkgid, failure) <- failures
+      , case buildFailureReason failure of
           DependentFailed {} -> False
           _                  -> True
       , InstallPlan.Configured pkg <-
@@ -515,10 +515,10 @@ reportBuildFailures plan buildOutcomes
     --  - then we do not report additional error detail or context.
     --
     isSimpleCase
-      | [(pkgid, reason)] <- failures
-      , [pkg]             <- rootpkgs
+      | [(pkgid, failure)] <- failures
+      , [pkg]              <- rootpkgs
       , installedUnitId pkg == pkgid
-      , isFailureSelfExplanatory reason
+      , isFailureSelfExplanatory (buildFailureReason failure)
       = True
       | otherwise
       = False
diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs
index c802b999435f2d9b9068f46f773c2e16978529a8..3c7d2ae11e54f81581a7044a42f37a720f66a939 100644
--- a/cabal-install/tests/IntegrationTests2.hs
+++ b/cabal-install/tests/IntegrationTests2.hs
@@ -94,8 +94,8 @@ testExceptionInConfigureStep :: ProjectConfig -> Assertion
 testExceptionInConfigureStep config = do
     (plan, res) <- executePlan =<< planProject testdir config
     (_pkga1, failure) <- expectPackageFailed plan res pkgidA1
-    case failure of
-      ConfigureFailed _str -> return ()
+    case buildFailureReason failure of
+      ConfigureFailed _ -> return ()
       _ -> assertFailure $ "expected ConfigureFailed, got " ++ show failure 
     cleanProject testdir
   where
@@ -405,9 +405,9 @@ expectPlanPackage plan pkgid =
                 ++ " in the install plan but there's several"
 
 expectBuildFailed :: BuildFailure -> IO ()
-expectBuildFailed (BuildFailed _str) = return ()
-expectBuildFailed failure = assertFailure $ "expected BuildFailed, got "
-                                         ++ show failure
+expectBuildFailed (BuildFailure _ (BuildFailed _)) = return ()
+expectBuildFailed (BuildFailure _ reason) =
+    assertFailure $ "expected BuildFailed, got " ++ show reason
 
 ---------------------------------------
 -- Other utils