David Eichmann pushed to branch wip/davide/hadrian_avoid_response_files_2 at Glasgow Haskell Compiler / GHC
Commits:
-
aea1d1d8
by David Eichmann at 2026-06-02T12:27:26+01:00
3 changed files:
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
|
| ... | ... | @@ -351,9 +351,11 @@ instance H.Builder Builder where |
| 351 | 351 | -- NB: we can't put the buildArgs in a response file, because some flags require
|
| 352 | 352 | -- empty arguments (such as the -dep-suffix flag), but that isn't supported
|
| 353 | 353 | -- yet due to #26560.
|
| 354 | - withResponseFileOnWindows
|
|
| 355 | - (\buildInputs' -> cmd [path] buildArgs buildInputs' buildOptions)
|
|
| 354 | + withResponseFileIfLongCmd
|
|
| 355 | + output
|
|
| 356 | + (toCmdArgument path <> toCmdArgument buildArgs)
|
|
| 356 | 357 | buildInputs
|
| 358 | + (toCmdArgument buildOptions)
|
|
| 357 | 359 | |
| 358 | 360 | HsCpp -> captureStdout
|
| 359 | 361 | |
| ... | ... | @@ -389,13 +391,16 @@ instance H.Builder Builder where |
| 389 | 391 | |
| 390 | 392 | -- | Invoke @haddock@ given a path to it and a list of arguments. On Windows,
|
| 391 | 393 | -- the input file arguments are passed as a response file.
|
| 392 | -runHaddock :: FilePath -- ^ path to @haddock@
|
|
| 394 | +runHaddock :: FilePath -- ^ output file path
|
|
| 395 | + -> FilePath -- ^ path to @haddock@
|
|
| 393 | 396 | -> [String]
|
| 394 | 397 | -> [FilePath] -- ^ input file paths
|
| 395 | 398 | -> Action ()
|
| 396 | -runHaddock haddockPath flagArgs fileInputs = withResponseFileOnWindows
|
|
| 397 | - (cmd [haddockPath] flagArgs)
|
|
| 399 | +runHaddock outputFilePath haddockPath flagArgs fileInputs = withResponseFileIfLongCmd
|
|
| 400 | + outputFilePath
|
|
| 401 | + (toCmdArgument haddockPath <> toCmdArgument flagArgs)
|
|
| 398 | 402 | fileInputs
|
| 403 | + (CmdArgument [])
|
|
| 399 | 404 | |
| 400 | 405 | -- TODO: Some builders are required only on certain platforms. For example,
|
| 401 | 406 | -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
|
| ... | ... | @@ -35,12 +35,13 @@ instance NFData ArMode |
| 35 | 35 | -- to be archived is passed via a temporary response file. Passing arguments
|
| 36 | 36 | -- via a response file is not supported by some versions of @ar@, in which
|
| 37 | 37 | -- case you should use 'runArWithoutTempFile' instead.
|
| 38 | -runAr :: FilePath -- ^ path to @ar@
|
|
| 38 | +runAr :: FilePath -- ^ Output file path
|
|
| 39 | + -> FilePath -- ^ path to @ar@
|
|
| 39 | 40 | -> [String] -- ^ other arguments
|
| 40 | 41 | -> [FilePath] -- ^ input file paths
|
| 41 | 42 | -> [CmdOption] -- ^ Additional options
|
| 42 | 43 | -> Action ()
|
| 43 | -runAr arPath flagArgs fileArgs buildOptions = withResponseFile $ \tmp -> do
|
|
| 44 | +runAr outputFile arPath flagArgs fileArgs buildOptions = withResponseFile outputFile $ \tmp -> do
|
|
| 44 | 45 | writeFile' tmp $ unwords fileArgs
|
| 45 | 46 | cmd [arPath] flagArgs ('@' : tmp) buildOptions
|
| 46 | 47 |
| 1 | +{-# LANGUAGE ImpredicativeTypes #-}
|
|
| 1 | 2 | {-# LANGUAGE TypeFamilies #-}
|
| 3 | + |
|
| 2 | 4 | module Hadrian.Utilities (
|
| 3 | 5 | -- * List manipulation
|
| 4 | 6 | fromSingleton, replaceEq, minusOrd, intersectOrd, lookupAll, chunksOfSize,
|
| ... | ... | @@ -14,7 +16,7 @@ module Hadrian.Utilities ( |
| 14 | 16 | |
| 15 | 17 | -- * Paths
|
| 16 | 18 | BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
|
| 17 | - KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileOnWindows,
|
|
| 19 | + KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileIfLongCmd,
|
|
| 18 | 20 | |
| 19 | 21 | -- * File system operations
|
| 20 | 22 | copyFile, copyFileUntracked, createFileLink, fixFile,
|
| ... | ... | @@ -50,7 +52,6 @@ import Development.Shake.Classes |
| 50 | 52 | import Development.Shake.FilePath
|
| 51 | 53 | import GHC.ResponseFile (escapeArgs)
|
| 52 | 54 | import System.Environment (lookupEnv)
|
| 53 | -import System.Info.Extra (isWindows)
|
|
| 54 | 55 | import System.IO (hClose, openTempFile)
|
| 55 | 56 | import System.IO.Error (isPermissionError)
|
| 56 | 57 | |
| ... | ... | @@ -61,6 +62,7 @@ import qualified System.Directory.Extra as IO |
| 61 | 62 | import qualified System.Info.Extra as IO
|
| 62 | 63 | import qualified System.IO as IO
|
| 63 | 64 | import qualified System.FilePath.Posix as Posix
|
| 65 | +import Development.Shake.Command (CmdArgument (..), IsCmdArgument (toCmdArgument))
|
|
| 64 | 66 | |
| 65 | 67 | -- | Extract a value from a singleton list, or terminate with an error message
|
| 66 | 68 | -- if the list does not contain exactly one value.
|
| ... | ... | @@ -330,26 +332,33 @@ keepResponseFiles = do |
| 330 | 332 | KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
|
| 331 | 333 | return keep
|
| 332 | 334 | |
| 333 | --- | Run an action either with command arguments direcly or by, on Windows,
|
|
| 334 | --- placing those arguments into a response file escaped with @GHC.ResponseFile.escapeArgs@.
|
|
| 335 | +-- | Run an command with the given arguments. If the command is too long then the
|
|
| 336 | +-- response file arguments are placed into a response file and escaped with @GHC.ResponseFile.escapeArgs@.
|
|
| 335 | 337 | --
|
| 336 | 338 | -- With @--keep-response-files@, the file is left on disk (if used)
|
| 337 | -withResponseFileOnWindows ::
|
|
| 338 | - ([String] -> Action a) -- ^ Action to perform given arguments (of the form @["\@reponseFilePath"]@ on Windows)
|
|
| 339 | - -> [String] -- ^ Command arguments
|
|
| 340 | - -> Action a
|
|
| 341 | -withResponseFileOnWindows action commandArgs = do
|
|
| 342 | - if isWindows
|
|
| 343 | - then withResponseFile $ \tmp -> do
|
|
| 344 | - writeFile' tmp (escapeArgs commandArgs)
|
|
| 345 | - action ['@' : tmp]
|
|
| 346 | - else action commandArgs
|
|
| 339 | +withResponseFileIfLongCmd :: (CmdResult c) =>
|
|
| 340 | + FilePath -- ^ Output file path. The response file is kept next to this with extension .rsp.
|
|
| 341 | + -> CmdArgument -- ^ Command and arguments before the response file arguments.
|
|
| 342 | + -> [String] -- ^ Response file aruguments.
|
|
| 343 | + -> CmdArgument -- ^ Command arguments after the response file arguments.
|
|
| 344 | + -> Action c
|
|
| 345 | +withResponseFileIfLongCmd outputFile argsPre argsResp argsPost = do
|
|
| 346 | + let cmdLineLengh = sum
|
|
| 347 | + [ length arg
|
|
| 348 | + | let CmdArgument args = argsPre <> toCmdArgument argsResp <> argsPost
|
|
| 349 | + , Right arg <- args
|
|
| 350 | + ]
|
|
| 351 | + if cmdLineLengh >= cmdLineLengthLimit
|
|
| 352 | + then withResponseFile outputFile $ \tmp -> do
|
|
| 353 | + writeFile' tmp (escapeArgs argsResp)
|
|
| 354 | + cmd argsPre ('@' : tmp) argsPost
|
|
| 355 | + else cmd argsPre argsResp argsPost
|
|
| 347 | 356 | |
| 348 | 357 | -- | Run an action with a response file path.
|
| 349 | 358 | --
|
| 350 | 359 | -- With @--keep-response-files@, the file is left on disk.
|
| 351 | -withResponseFile :: (FilePath -> Action a) -> Action a
|
|
| 352 | -withResponseFile action = do
|
|
| 360 | +withResponseFile :: FilePath -> (FilePath -> Action a) -> Action a
|
|
| 361 | +withResponseFile outputFile action = do
|
|
| 353 | 362 | keep <- keepResponseFiles
|
| 354 | 363 | let putVerboseResponseFile tmp = do
|
| 355 | 364 | verbosity <- getVerbosity
|
| ... | ... | @@ -358,7 +367,9 @@ withResponseFile action = do |
| 358 | 367 | putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
|
| 359 | 368 | if keep
|
| 360 | 369 | then do
|
| 361 | - (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
|
|
| 370 | + let dir = takeDirectory outputFile
|
|
| 371 | + file = takeFileName outputFile <.> "rsp"
|
|
| 372 | + (tmp, h) <- liftIO $ openTempFile dir file
|
|
| 362 | 373 | liftIO $ hClose h
|
| 363 | 374 | putInfo $ "Keeping response file: " ++ tmp
|
| 364 | 375 | result <- action tmp
|