{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.Program.Ld (
combineObjectFiles,
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Simple.Compiler (arResponseFilesSupported)
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
import Distribution.Simple.Program.ResponseFile
( withResponseFile )
import Distribution.Simple.Program.Run
( ProgramInvocation, programInvocation, multiStageProgramInvocation
, runProgramInvocation )
import Distribution.Simple.Program.Types
( ConfiguredProgram(..) )
import Distribution.Simple.Setup
( fromFlagOrDefault, configUseResponseFiles )
import Distribution.Simple.Utils
( defaultTempFileOptions )
import Distribution.Verbosity
( Verbosity )
import System.Directory
( renameFile )
import System.FilePath
( (<.>), takeDirectory )
combineObjectFiles :: Verbosity -> LocalBuildInfo -> ConfiguredProgram
-> FilePath -> [FilePath] -> IO ()
combineObjectFiles verbosity lbi ld target files = do
let simpleArgs = ["-r", "-o", target]
initialArgs = ["-r", "-o", target]
middleArgs = ["-r", "-o", target, tmpfile]
finalArgs = middleArgs
simple = programInvocation ld simpleArgs
initial = programInvocation ld initialArgs
middle = programInvocation ld middleArgs
final = programInvocation ld finalArgs
targetDir = takeDirectory target
invokeWithResponesFile :: FilePath -> ProgramInvocation
invokeWithResponesFile atFile =
programInvocation ld $ simpleArgs ++ ['@' : atFile]
oldVersionManualOverride =
fromFlagOrDefault False $ configUseResponseFiles $ configFlags lbi
responseArgumentsNotSupported =
not (arResponseFilesSupported (compiler lbi))
if oldVersionManualOverride || responseArgumentsNotSupported
then
run $ multiStageProgramInvocation simple (initial, middle, final) files
else
withResponseFile verbosity defaultTempFileOptions targetDir "ld.rsp" Nothing files $
\path -> runProgramInvocation verbosity $ invokeWithResponesFile path
where
tmpfile = target <.> "tmp"
run :: [ProgramInvocation] -> IO ()
run [] = return ()
run [inv] = runProgramInvocation verbosity inv
run (inv:invs) = do runProgramInvocation verbosity inv
renameFile target tmpfile
run invs