1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE RankNTypes #-}
4 -----------------------------------------------------------------------------
7 -- Module : Distribution.Simple.Program.Ld
8 -- Copyright : Duncan Coutts 2009
10 -- Maintainer : cabal-devel@haskell.org
11 -- Portability : portable
13 -- This module provides an library interface to the @ld@ linker program.
14 module Distribution
.Simple
.Program
.Ld
18 import Distribution
.Compat
.Prelude
21 import Distribution
.Simple
.Compiler
(arResponseFilesSupported
)
22 import Distribution
.Simple
.Flag
25 import Distribution
.Simple
.LocalBuildInfo
(LocalBuildInfo
(..))
26 import Distribution
.Simple
.Program
.ResponseFile
29 import Distribution
.Simple
.Program
.Run
31 , multiStageProgramInvocation
33 , runProgramInvocation
35 import Distribution
.Simple
.Program
.Types
36 ( ConfiguredProgram
(..)
38 import Distribution
.Simple
.Setup
.Config
39 ( configUseResponseFiles
41 import Distribution
.Simple
.Utils
42 ( defaultTempFileOptions
44 import Distribution
.Verbosity
48 import System
.Directory
51 import System
.FilePath
56 -- | Call @ld -r@ to link a bunch of object files together.
64 combineObjectFiles verbosity lbi ld target files
= do
65 -- Unlike "ar", the "ld" tool is not designed to be used with xargs. That is,
66 -- if we have more object files than fit on a single command line then we
67 -- have a slight problem. What we have to do is link files in batches into
68 -- a temp object file and then include that one in the next batch.
70 let simpleArgs
= ["-r", "-o", target
]
72 initialArgs
= ["-r", "-o", target
]
73 middleArgs
= ["-r", "-o", target
, tmpfile
]
74 finalArgs
= middleArgs
76 simple
= programInvocation ld simpleArgs
77 initial
= programInvocation ld initialArgs
78 middle
= programInvocation ld middleArgs
79 final
= programInvocation ld finalArgs
81 targetDir
= takeDirectory target
83 invokeWithResponesFile
:: FilePath -> ProgramInvocation
84 invokeWithResponesFile atFile
=
85 programInvocation ld
$ simpleArgs
++ ['@' : atFile
]
87 oldVersionManualOverride
=
88 fromFlagOrDefault
False $ configUseResponseFiles
$ configFlags lbi
89 -- Whether ghc's ar supports response files is a good proxy for
90 -- whether ghc's ld supports them as well.
91 responseArgumentsNotSupported
=
92 not (arResponseFilesSupported
(compiler lbi
))
94 if oldVersionManualOverride || responseArgumentsNotSupported
95 then run
$ multiStageProgramInvocation simple
(initial
, middle
, final
) files
96 else withResponseFile verbosity defaultTempFileOptions targetDir
"ld.rsp" Nothing files
$
97 \path
-> runProgramInvocation verbosity
$ invokeWithResponesFile path
99 tmpfile
= target
<.> "tmp" -- perhaps should use a proper temp file
100 run
:: [ProgramInvocation
] -> IO ()
102 run
[inv
] = runProgramInvocation verbosity inv
103 run
(inv
: invs
) = do
104 runProgramInvocation verbosity inv
105 renameFile target tmpfile