Cabal-2.0.0.2: Distribution/Simple/Program/Ld.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Simple.Program.Ld
-- Copyright : Duncan Coutts 2009
--
-- Maintainer : cabal-devel@haskell.org
-- Portability : portable
--
-- This module provides an library interface to the @ld@ linker program.
module Distribution.Simple.Program.Ld (
combineObjectFiles,
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Simple.Program.Types
( ConfiguredProgram(..) )
import Distribution.Simple.Program.Run
( programInvocation, multiStageProgramInvocation
, runProgramInvocation )
import Distribution.Verbosity
( Verbosity )
import System.Directory
( renameFile )
import System.FilePath
( (<.>) )
-- | Call @ld -r@ to link a bunch of object files together.
--
combineObjectFiles :: Verbosity -> ConfiguredProgram
-> FilePath -> [FilePath] -> IO ()
combineObjectFiles verbosity ld target files =
-- Unlike "ar", the "ld" tool is not designed to be used with xargs. That is,
-- if we have more object files than fit on a single command line then we
-- have a slight problem. What we have to do is link files in batches into
-- a temp object file and then include that one in the next batch.
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
invocations = multiStageProgramInvocation
simple (initial, middle, final) files
in run invocations
where
tmpfile = target <.> "tmp" -- perhaps should use a proper temp file
run [] = return ()
run [inv] = runProgramInvocation verbosity inv
run (inv:invs) = do runProgramInvocation verbosity inv
renameFile target tmpfile
run invs