David Eichmann pushed to branch wip/davide/hadrian_avoid_response_files_2 at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • hadrian/src/Builder.hs
    ... ... @@ -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
    

  • hadrian/src/Hadrian/Builder/Ar.hs
    ... ... @@ -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
     
    

  • hadrian/src/Hadrian/Utilities.hs
    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