David Eichmann pushed to branch wip/davide/hadrian_avoid_response_files_2 at Glasgow Haskell Compiler / GHC
Commits:
-
ff6d11f9
by David Eichmann at 2026-06-03T15:03:06+01:00
4 changed files:
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Utilities.hs
Changes:
| ... | ... | @@ -304,7 +304,7 @@ instance H.Builder Builder where |
| 304 | 304 | case builder of
|
| 305 | 305 | Ar Pack stg -> do
|
| 306 | 306 | useTempFile <- arSupportsAtFile stg
|
| 307 | - if useTempFile then runAr path buildArgs buildInputs buildOptions
|
|
| 307 | + if useTempFile then runAr output path buildArgs buildInputs buildOptions
|
|
| 308 | 308 | else runArWithoutTempFile path buildArgs buildInputs buildOptions
|
| 309 | 309 | |
| 310 | 310 | Ar Unpack _ -> cmd' [Cwd output] [path] buildArgs buildOptions
|
| ... | ... | @@ -343,7 +343,7 @@ instance H.Builder Builder where |
| 343 | 343 | Exit _ <- cmd' [path] (buildArgs ++ [input]) buildOptions
|
| 344 | 344 | return ()
|
| 345 | 345 | |
| 346 | - Haddock BuildPackage -> runHaddock path buildArgs buildInputs
|
|
| 346 | + Haddock BuildPackage -> runHaddock output path buildArgs buildInputs
|
|
| 347 | 347 | |
| 348 | 348 | Ghc _ _ ->
|
| 349 | 349 | -- Use a response file for ghc invocations to avoid issues with command line
|
| ... | ... | @@ -352,6 +352,7 @@ instance H.Builder Builder where |
| 352 | 352 | -- empty arguments (such as the -dep-suffix flag), but that isn't supported
|
| 353 | 353 | -- yet due to #26560.
|
| 354 | 354 | withResponseFileIfLongCmd
|
| 355 | + output
|
|
| 355 | 356 | (toCmdArgument [path] <> toCmdArgument buildArgs)
|
| 356 | 357 | buildInputs
|
| 357 | 358 | (toCmdArgument buildOptions)
|
| ... | ... | @@ -390,11 +391,13 @@ instance H.Builder Builder where |
| 390 | 391 | |
| 391 | 392 | -- | Invoke @haddock@ given a path to it and a list of arguments. On Windows,
|
| 392 | 393 | -- the input file arguments are passed as a response file.
|
| 393 | -runHaddock :: FilePath -- ^ path to @haddock@
|
|
| 394 | +runHaddock :: FilePath -- ^ output file path
|
|
| 395 | + -> FilePath -- ^ path to @haddock@
|
|
| 394 | 396 | -> [String]
|
| 395 | 397 | -> [FilePath] -- ^ input file paths
|
| 396 | 398 | -> Action ()
|
| 397 | -runHaddock haddockPath flagArgs fileInputs = withResponseFileIfLongCmd
|
|
| 399 | +runHaddock outputFilePath haddockPath flagArgs fileInputs = withResponseFileIfLongCmd
|
|
| 400 | + outputFilePath
|
|
| 398 | 401 | (toCmdArgument [haddockPath] <> toCmdArgument flagArgs)
|
| 399 | 402 | fileInputs
|
| 400 | 403 | (CmdArgument [])
|
| ... | ... | @@ -3,8 +3,7 @@ module CommandLine ( |
| 3 | 3 | lookupBignum,
|
| 4 | 4 | cmdBignum, cmdProgressInfo, cmdCompleteSetting,
|
| 5 | 5 | cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs,
|
| 6 | - cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs,
|
|
| 7 | - cmdKeepResponseFiles
|
|
| 6 | + cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs
|
|
| 8 | 7 | ) where
|
| 9 | 8 | |
| 10 | 9 | import Data.Either
|
| ... | ... | @@ -12,7 +11,7 @@ import qualified Data.HashMap.Strict as Map |
| 12 | 11 | import Data.List.Extra
|
| 13 | 12 | import Development.Shake hiding (Normal)
|
| 14 | 13 | import Flavour (DocTargets, DocTarget(..))
|
| 15 | -import Hadrian.Utilities hiding (buildRoot, keepResponseFiles)
|
|
| 14 | +import Hadrian.Utilities hiding (buildRoot)
|
|
| 16 | 15 | import Settings.Parser
|
| 17 | 16 | import System.Console.GetOpt
|
| 18 | 17 | import System.Environment
|
| ... | ... | @@ -37,7 +36,6 @@ data CommandLineArgs = CommandLineArgs |
| 37 | 36 | , testArgs :: TestArgs
|
| 38 | 37 | , docsArgs :: DocArgs
|
| 39 | 38 | , docTargets :: DocTargets
|
| 40 | - , keepResponseFiles :: Bool
|
|
| 41 | 39 | , prefix :: Maybe FilePath
|
| 42 | 40 | , changelogVersion :: Maybe String
|
| 43 | 41 | , completeStg :: Maybe String }
|
| ... | ... | @@ -58,7 +56,6 @@ defaultCommandLineArgs = CommandLineArgs |
| 58 | 56 | , testArgs = defaultTestArgs
|
| 59 | 57 | , docsArgs = defaultDocArgs
|
| 60 | 58 | , docTargets = Set.fromList [minBound..maxBound]
|
| 61 | - , keepResponseFiles = False
|
|
| 62 | 59 | , prefix = Nothing
|
| 63 | 60 | , changelogVersion = Nothing
|
| 64 | 61 | , completeStg = Nothing }
|
| ... | ... | @@ -141,9 +138,6 @@ readFreeze1 = Right $ \flags -> flags { freeze1 = True } |
| 141 | 138 | readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True }
|
| 142 | 139 | readSkipDepends = Right $ \flags -> flags { skipDepends = True }
|
| 143 | 140 | |
| 144 | -readKeepResponseFiles :: Either String (CommandLineArgs -> CommandLineArgs)
|
|
| 145 | -readKeepResponseFiles = Right $ \flags -> flags { keepResponseFiles = True }
|
|
| 146 | - |
|
| 147 | 141 | readUnitIdHash :: Either String (CommandLineArgs -> CommandLineArgs)
|
| 148 | 142 | readUnitIdHash = Right $ \flags ->
|
| 149 | 143 | trace "--hash-unit-ids is deprecated. It is enabled by release flavour or +hash_unit_ids flavour transformer" $
|
| ... | ... | @@ -302,8 +296,6 @@ optDescrs = |
| 302 | 296 | "Progress info style (None, Brief, Normal or Unicorn)."
|
| 303 | 297 | , Option [] ["docs"] (ReqArg readDocsArg "TARGET")
|
| 304 | 298 | "Strip down docs targets (none, no-haddocks, no-sphinx[-{html, pdfs, man}]."
|
| 305 | - , Option ['r'] ["keep-response-files"] (NoArg readKeepResponseFiles)
|
|
| 306 | - "Keep response files created during the build (for debugging)."
|
|
| 307 | 299 | , Option ['k'] ["keep-test-files"] (NoArg readTestKeepFiles)
|
| 308 | 300 | "Keep all the files generated when running the testsuite."
|
| 309 | 301 | , Option [] ["test-compiler"] (ReqArg readTestCompiler "TEST_COMPILER")
|
| ... | ... | @@ -382,7 +374,6 @@ cmdLineArgsMap = do |
| 382 | 374 | |
| 383 | 375 | return $ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
|
| 384 | 376 | $ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
|
| 385 | - $ insertExtra (KeepResponseFiles $ keepResponseFiles args) -- Accessed by Hadrian.Utilities
|
|
| 386 | 377 | $ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
|
| 387 | 378 | $ insertExtra (docsArgs args) -- Accessed by Rules.Documentation
|
| 388 | 379 | $ insertExtra allSettings -- Accessed by Settings
|
| ... | ... | @@ -424,9 +415,6 @@ cmdUnitIdHash = unitIdHash <$> cmdLineArgs |
| 424 | 415 | cmdBignum :: Action (Maybe String)
|
| 425 | 416 | cmdBignum = bignum <$> cmdLineArgs
|
| 426 | 417 | |
| 427 | -cmdKeepResponseFiles :: Action Bool
|
|
| 428 | -cmdKeepResponseFiles = keepResponseFiles <$> cmdLineArgs
|
|
| 429 | - |
|
| 430 | 418 | cmdProgressInfo :: Action ProgressInfo
|
| 431 | 419 | cmdProgressInfo = progressInfo <$> cmdLineArgs
|
| 432 | 420 |
| ... | ... | @@ -23,6 +23,7 @@ import Development.Shake |
| 23 | 23 | import Development.Shake.Classes
|
| 24 | 24 | import GHC.Generics
|
| 25 | 25 | import Hadrian.Utilities
|
| 26 | +import System.FilePath ((<.>))
|
|
| 26 | 27 | |
| 27 | 28 | -- | We support packing and unpacking archives with @ar@.
|
| 28 | 29 | data ArMode = Pack | Unpack deriving (Eq, Generic, Show)
|
| ... | ... | @@ -35,14 +36,16 @@ instance NFData ArMode |
| 35 | 36 | -- to be archived is passed via a temporary response file. Passing arguments
|
| 36 | 37 | -- via a response file is not supported by some versions of @ar@, in which
|
| 37 | 38 | -- case you should use 'runArWithoutTempFile' instead.
|
| 38 | -runAr :: FilePath -- ^ path to @ar@
|
|
| 39 | +runAr :: FilePath -- ^ output file path
|
|
| 40 | + -> FilePath -- ^ path to @ar@
|
|
| 39 | 41 | -> [String] -- ^ other arguments
|
| 40 | 42 | -> [FilePath] -- ^ input file paths
|
| 41 | 43 | -> [CmdOption] -- ^ Additional options
|
| 42 | 44 | -> Action ()
|
| 43 | -runAr arPath flagArgs fileArgs buildOptions = withResponseFile $ \tmp -> do
|
|
| 44 | - writeFile' tmp $ unwords fileArgs
|
|
| 45 | - cmd [arPath] flagArgs ('@' : tmp) buildOptions
|
|
| 45 | +runAr outputFilePath arPath flagArgs fileArgs buildOptions = do
|
|
| 46 | + let rspFile = outputFilePath <.> "rsp"
|
|
| 47 | + writeFile' rspFile $ unwords fileArgs
|
|
| 48 | + cmd [arPath] flagArgs ('@' : rspFile) buildOptions
|
|
| 46 | 49 | |
| 47 | 50 | -- | Invoke @ar@ given a path to it and a list of arguments. Note that @ar@
|
| 48 | 51 | -- will be called multiple times if the list of files to be archived is too
|
| ... | ... | @@ -16,7 +16,7 @@ module Hadrian.Utilities ( |
| 16 | 16 | |
| 17 | 17 | -- * Paths
|
| 18 | 18 | BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
|
| 19 | - KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileIfLongCmd,
|
|
| 19 | + withResponseFileIfLongCmd,
|
|
| 20 | 20 | |
| 21 | 21 | -- * File system operations
|
| 22 | 22 | copyFile, copyFileUntracked, createFileLink, fixFile,
|
| ... | ... | @@ -52,7 +52,6 @@ import Development.Shake.Classes |
| 52 | 52 | import Development.Shake.FilePath
|
| 53 | 53 | import GHC.ResponseFile (escapeArgs)
|
| 54 | 54 | import System.Environment (lookupEnv)
|
| 55 | -import System.IO (hClose, openTempFile)
|
|
| 56 | 55 | import System.IO.Error (isPermissionError)
|
| 57 | 56 | |
| 58 | 57 | import qualified Data.ByteString as BS
|
| ... | ... | @@ -323,59 +322,28 @@ buildRootRules = do |
| 323 | 322 | isGeneratedSource :: FilePath -> Action Bool
|
| 324 | 323 | isGeneratedSource file = buildRoot <&> (`isPrefixOf` file)
|
| 325 | 324 | |
| 326 | -newtype KeepResponseFiles = KeepResponseFiles Bool deriving (Eq, Show)
|
|
| 327 | - |
|
| 328 | --- | Whether to retain response files after the build action that created them
|
|
| 329 | --- completes. Mainly useful for debugging.
|
|
| 330 | -keepResponseFiles :: Action Bool
|
|
| 331 | -keepResponseFiles = do
|
|
| 332 | - KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
|
|
| 333 | - return keep
|
|
| 334 | - |
|
| 335 | 325 | -- | Run an command with the given arguments. If the command is too long then the
|
| 336 | 326 | -- response file arguments are placed into a response file and escaped with @GHC.ResponseFile.escapeArgs@.
|
| 337 | 327 | --
|
| 338 | 328 | -- With @--keep-response-files@, the file is left on disk (if used)
|
| 339 | 329 | withResponseFileIfLongCmd :: (CmdResult c) =>
|
| 340 | - CmdArgument -- ^ Command and arguments before the response file arguments.
|
|
| 330 | + FilePath -- ^ Command output file. The reponse file is placed next to this
|
|
| 331 | + -> CmdArgument -- ^ Command and arguments before the response file arguments.
|
|
| 341 | 332 | -> [String] -- ^ Response file aruguments.
|
| 342 | 333 | -> CmdArgument -- ^ Command arguments after the response file arguments.
|
| 343 | 334 | -> Action c
|
| 344 | -withResponseFileIfLongCmd argsPre argsResp argsPost = do
|
|
| 335 | +withResponseFileIfLongCmd outputFilePath argsPre argsResp argsPost = do
|
|
| 345 | 336 | let cmdLineLengh = sum
|
| 346 | 337 | [ 1 + length arg -- add one to account for space inbetween arguments
|
| 347 | 338 | | let CmdArgument args = argsPre <> toCmdArgument argsResp <> argsPost
|
| 348 | 339 | , Right arg <- args
|
| 349 | 340 | ]
|
| 350 | - if cmdLineLengh >= cmdLineLengthLimit
|
|
| 351 | - then withResponseFile $ \tmp -> do
|
|
| 352 | - writeFile' tmp (escapeArgs argsResp)
|
|
| 353 | - cmd argsPre ['@' : tmp] argsPost
|
|
| 354 | - else cmd argsPre argsResp argsPost
|
|
| 355 | - |
|
| 356 | --- | Run an action with a response file path.
|
|
| 357 | ---
|
|
| 358 | --- With @--keep-response-files@, the file is left on disk.
|
|
| 359 | -withResponseFile :: (FilePath -> Action a) -> Action a
|
|
| 360 | -withResponseFile action = do
|
|
| 361 | - keep <- keepResponseFiles
|
|
| 362 | - let putVerboseResponseFile tmp = do
|
|
| 363 | - verbosity <- getVerbosity
|
|
| 364 | - when (verbosity >= Verbose) $ do
|
|
| 365 | - tmpContent <- liftIO (readFile tmp)
|
|
| 366 | - putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
|
|
| 367 | - if keep
|
|
| 368 | - then do
|
|
| 369 | - (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
|
|
| 370 | - liftIO $ hClose h
|
|
| 371 | - putInfo $ "Keeping response file: " ++ tmp
|
|
| 372 | - result <- action tmp
|
|
| 373 | - putVerboseResponseFile tmp
|
|
| 374 | - return result
|
|
| 375 | - else withTempFile $ \tmp -> do
|
|
| 376 | - result <- action tmp
|
|
| 377 | - putVerboseResponseFile tmp
|
|
| 378 | - return result
|
|
| 341 | + if cmdLineLengh < cmdLineLengthLimit
|
|
| 342 | + then cmd argsPre argsResp argsPost
|
|
| 343 | + else do
|
|
| 344 | + let rspFile = outputFilePath <.> "rsp"
|
|
| 345 | + writeFile' rspFile (escapeArgs argsResp)
|
|
| 346 | + cmd argsPre ['@' : rspFile] argsPost
|
|
| 379 | 347 | |
| 380 | 348 | -- | Link a file tracking the link target. Create the target directory if
|
| 381 | 349 | -- missing.
|