Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
42549222
by sheaf at 2026-04-27T09:33:50-04:00
5 changed files:
- + changelog.d/hadrian-response-files.md
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Utilities.hs
Changes:
| 1 | +section: packaging
|
|
| 2 | +synopsis: Add a flag to tell Hadrian to keep response files
|
|
| 3 | +issues: #27184
|
|
| 4 | +mrs: !15906
|
|
| 5 | +description:
|
|
| 6 | + Hadrian can now be instructed to keep response files with the new
|
|
| 7 | + --keep-response-files command line flag. This is helpful when debugging a
|
|
| 8 | + build failure, as it allows re-running the failing command line invocation
|
|
| 9 | + without an error due to a missing response file. |
| ... | ... | @@ -389,15 +389,13 @@ runHaddock :: FilePath -- ^ path to @haddock@ |
| 389 | 389 | -> [String]
|
| 390 | 390 | -> [FilePath] -- ^ input file paths
|
| 391 | 391 | -> Action ()
|
| 392 | -runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do
|
|
| 392 | +runHaddock haddockPath flagArgs fileInputs = withResponseFile $ \tmp -> do
|
|
| 393 | 393 | writeFile' tmp $ escapeArgs fileInputs
|
| 394 | 394 | cmd [haddockPath] flagArgs ('@' : tmp)
|
| 395 | 395 | |
| 396 | 396 | runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
|
| 397 | -runGhcWithResponse ghcPath flagArgs fileInputs = withTempFile $ \tmp -> do
|
|
| 398 | - |
|
| 397 | +runGhcWithResponse ghcPath flagArgs fileInputs = withResponseFile $ \tmp -> do
|
|
| 399 | 398 | writeFile' tmp $ escapeArgs fileInputs
|
| 400 | - |
|
| 401 | 399 | -- We can't put the flags in a response file, because some flags
|
| 402 | 400 | -- require empty arguments (such as the -dep-suffix flag), but
|
| 403 | 401 | -- that isn't supported yet due to #26560.
|
| ... | ... | @@ -3,7 +3,8 @@ module CommandLine ( |
| 3 | 3 | lookupBignum,
|
| 4 | 4 | cmdBignum, cmdBignumCheck, cmdProgressInfo, cmdCompleteSetting,
|
| 5 | 5 | cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs,
|
| 6 | - cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs
|
|
| 6 | + cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs,
|
|
| 7 | + cmdKeepResponseFiles
|
|
| 7 | 8 | ) where
|
| 8 | 9 | |
| 9 | 10 | import Data.Either
|
| ... | ... | @@ -11,7 +12,7 @@ import qualified Data.HashMap.Strict as Map |
| 11 | 12 | import Data.List.Extra
|
| 12 | 13 | import Development.Shake hiding (Normal)
|
| 13 | 14 | import Flavour (DocTargets, DocTarget(..))
|
| 14 | -import Hadrian.Utilities hiding (buildRoot)
|
|
| 15 | +import Hadrian.Utilities hiding (buildRoot, keepResponseFiles)
|
|
| 15 | 16 | import Settings.Parser
|
| 16 | 17 | import System.Console.GetOpt
|
| 17 | 18 | import System.Environment
|
| ... | ... | @@ -37,6 +38,7 @@ data CommandLineArgs = CommandLineArgs |
| 37 | 38 | , testArgs :: TestArgs
|
| 38 | 39 | , docsArgs :: DocArgs
|
| 39 | 40 | , docTargets :: DocTargets
|
| 41 | + , keepResponseFiles :: Bool
|
|
| 40 | 42 | , prefix :: Maybe FilePath
|
| 41 | 43 | , changelogVersion :: Maybe String
|
| 42 | 44 | , completeStg :: Maybe String }
|
| ... | ... | @@ -58,6 +60,7 @@ defaultCommandLineArgs = CommandLineArgs |
| 58 | 60 | , testArgs = defaultTestArgs
|
| 59 | 61 | , docsArgs = defaultDocArgs
|
| 60 | 62 | , docTargets = Set.fromList [minBound..maxBound]
|
| 63 | + , keepResponseFiles = False
|
|
| 61 | 64 | , prefix = Nothing
|
| 62 | 65 | , changelogVersion = Nothing
|
| 63 | 66 | , completeStg = Nothing }
|
| ... | ... | @@ -143,6 +146,9 @@ readFreeze1 = Right $ \flags -> flags { freeze1 = True } |
| 143 | 146 | readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True }
|
| 144 | 147 | readSkipDepends = Right $ \flags -> flags { skipDepends = True }
|
| 145 | 148 | |
| 149 | +readKeepResponseFiles :: Either String (CommandLineArgs -> CommandLineArgs)
|
|
| 150 | +readKeepResponseFiles = Right $ \flags -> flags { keepResponseFiles = True }
|
|
| 151 | + |
|
| 146 | 152 | readUnitIdHash :: Either String (CommandLineArgs -> CommandLineArgs)
|
| 147 | 153 | readUnitIdHash = Right $ \flags ->
|
| 148 | 154 | trace "--hash-unit-ids is deprecated. It is enabled by release flavour or +hash_unit_ids flavour transformer" $
|
| ... | ... | @@ -301,6 +307,8 @@ optDescrs = |
| 301 | 307 | "Progress info style (None, Brief, Normal or Unicorn)."
|
| 302 | 308 | , Option [] ["docs"] (ReqArg readDocsArg "TARGET")
|
| 303 | 309 | "Strip down docs targets (none, no-haddocks, no-sphinx[-{html, pdfs, man}]."
|
| 310 | + , Option ['r'] ["keep-response-files"] (NoArg readKeepResponseFiles)
|
|
| 311 | + "Keep response files created during the build (for debugging)."
|
|
| 304 | 312 | , Option ['k'] ["keep-test-files"] (NoArg readTestKeepFiles)
|
| 305 | 313 | "Keep all the files generated when running the testsuite."
|
| 306 | 314 | , Option [] ["test-compiler"] (ReqArg readTestCompiler "TEST_COMPILER")
|
| ... | ... | @@ -377,11 +385,12 @@ cmdLineArgsMap = do |
| 377 | 385 | else return []
|
| 378 | 386 | let allSettings = cliSettings ++ fileSettings
|
| 379 | 387 | |
| 380 | - return $ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
|
|
| 381 | - $ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
|
|
| 382 | - $ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
|
|
| 383 | - $ insertExtra (docsArgs args) -- Accessed by Rules.Documentation
|
|
| 384 | - $ insertExtra allSettings -- Accessed by Settings
|
|
| 388 | + return $ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
|
|
| 389 | + $ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
|
|
| 390 | + $ insertExtra (KeepResponseFiles $ keepResponseFiles args) -- Accessed by Hadrian.Utilities
|
|
| 391 | + $ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
|
|
| 392 | + $ insertExtra (docsArgs args) -- Accessed by Rules.Documentation
|
|
| 393 | + $ insertExtra allSettings -- Accessed by Settings
|
|
| 385 | 394 | $ insertExtra args Map.empty
|
| 386 | 395 | |
| 387 | 396 | cmdLineArgs :: Action CommandLineArgs
|
| ... | ... | @@ -423,6 +432,9 @@ cmdBignum = bignum <$> cmdLineArgs |
| 423 | 432 | cmdBignumCheck :: Action Bool
|
| 424 | 433 | cmdBignumCheck = bignumCheck <$> cmdLineArgs
|
| 425 | 434 | |
| 435 | +cmdKeepResponseFiles :: Action Bool
|
|
| 436 | +cmdKeepResponseFiles = keepResponseFiles <$> cmdLineArgs
|
|
| 437 | + |
|
| 426 | 438 | cmdProgressInfo :: Action ProgressInfo
|
| 427 | 439 | cmdProgressInfo = progressInfo <$> cmdLineArgs
|
| 428 | 440 |
| ... | ... | @@ -40,7 +40,7 @@ runAr :: FilePath -- ^ path to @ar@ |
| 40 | 40 | -> [FilePath] -- ^ input file paths
|
| 41 | 41 | -> [CmdOption] -- ^ Additional options
|
| 42 | 42 | -> Action ()
|
| 43 | -runAr arPath flagArgs fileArgs buildOptions = withTempFile $ \tmp -> do
|
|
| 43 | +runAr arPath flagArgs fileArgs buildOptions = withResponseFile $ \tmp -> do
|
|
| 44 | 44 | writeFile' tmp $ unwords fileArgs
|
| 45 | 45 | cmd [arPath] flagArgs ('@' : tmp) buildOptions
|
| 46 | 46 |
| ... | ... | @@ -14,6 +14,7 @@ module Hadrian.Utilities ( |
| 14 | 14 | |
| 15 | 15 | -- * Paths
|
| 16 | 16 | BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
|
| 17 | + KeepResponseFiles (..), keepResponseFiles, withResponseFile,
|
|
| 17 | 18 | |
| 18 | 19 | -- * File system operations
|
| 19 | 20 | copyFile, copyFileUntracked, createFileLink, fixFile,
|
| ... | ... | @@ -48,6 +49,7 @@ import Development.Shake hiding (Normal) |
| 48 | 49 | import Development.Shake.Classes
|
| 49 | 50 | import Development.Shake.FilePath
|
| 50 | 51 | import System.Environment (lookupEnv)
|
| 52 | +import System.IO (hClose, openTempFile)
|
|
| 51 | 53 | |
| 52 | 54 | import qualified Data.ByteString as BS
|
| 53 | 55 | import qualified Control.Exception.Base as IO
|
| ... | ... | @@ -317,6 +319,29 @@ buildRootRules = do |
| 317 | 319 | isGeneratedSource :: FilePath -> Action Bool
|
| 318 | 320 | isGeneratedSource file = buildRoot <&> (`isPrefixOf` file)
|
| 319 | 321 | |
| 322 | +newtype KeepResponseFiles = KeepResponseFiles Bool deriving (Eq, Show)
|
|
| 323 | + |
|
| 324 | +-- | Whether to retain response files after the build action that created them
|
|
| 325 | +-- completes. Mainly useful for debugging.
|
|
| 326 | +keepResponseFiles :: Action Bool
|
|
| 327 | +keepResponseFiles = do
|
|
| 328 | + KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
|
|
| 329 | + return keep
|
|
| 330 | + |
|
| 331 | +-- | Run an action with a response file path.
|
|
| 332 | +--
|
|
| 333 | +-- With @--keep-response-files@, the file is left on disk.
|
|
| 334 | +withResponseFile :: (FilePath -> Action a) -> Action a
|
|
| 335 | +withResponseFile action = do
|
|
| 336 | + keep <- keepResponseFiles
|
|
| 337 | + if keep
|
|
| 338 | + then do
|
|
| 339 | + (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
|
|
| 340 | + liftIO $ hClose h
|
|
| 341 | + putInfo $ "Keeping response file: " ++ tmp
|
|
| 342 | + action tmp
|
|
| 343 | + else withTempFile action
|
|
| 344 | + |
|
| 320 | 345 | -- | Link a file tracking the link target. Create the target directory if
|
| 321 | 346 | -- missing.
|
| 322 | 347 | createFileLink :: FilePath -> FilePath -> Action ()
|