Commit 7a623d00 authored by Duncan Coutts's avatar Duncan Coutts
Browse files

Add specialised modules for handling ar and ld

parent a6e3925c
......@@ -88,9 +88,11 @@ Library
Distribution.Simple.PreProcess,
Distribution.Simple.PreProcess.Unlit,
Distribution.Simple.Program,
Distribution.Simple.Program.Ar,
Distribution.Simple.Program.Builtin,
Distribution.Simple.Program.Db,
Distribution.Simple.Program.HcPkg,
Distribution.Simple.Program.Ld,
Distribution.Simple.Program.Run,
Distribution.Simple.Program.Script,
Distribution.Simple.Program.Types,
......
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Simple.Program.Ar
-- Copyright : Duncan Coutts 2009
--
-- Maintainer : cabal-devel@haskell.org
-- Portability : portable
--
-- This module provides an library interface to the @ar@ program.
module Distribution.Simple.Program.Ar (
createArLibArchive,
multiStageProgramInvocation,
) where
import Distribution.Simple.Program.Types
( ConfiguredProgram(..) )
import Distribution.Simple.Program.Run
( programInvocation, multiStageProgramInvocation
, runProgramInvocation )
import Distribution.System
( OS(..), buildOS )
import Distribution.Verbosity
( Verbosity, deafening, verbose )
-- | Call @ar@ to create a library archive from a bunch of object files.
--
createArLibArchive :: Verbosity -> ConfiguredProgram
-> FilePath -> [FilePath] -> IO ()
createArLibArchive verbosity ar target files =
-- The args to use with "ar" are actually rather subtle and system-dependent.
-- In particular we have the following issues:
--
-- -- On OS X, "ar q" does not make an archive index. Archives with no
-- index cannot be used.
--
-- -- GNU "ar r" will not let us add duplicate objects, only "ar q" lets us
-- do that. We have duplicates because of modules like "A.M" and "B.M"
-- both make an object file "M.o" and ar does not consider the directory.
--
-- Our solution is to use "ar r" in the simple case when one call is enough.
-- When we need to call ar multiple times we use "ar q" and for the last
-- call on OSX we use "ar qs" so that it'll make the index.
let simpleArgs = ["-r"]
initialArgs = ["-q"]
finalArgs = case buildOS of
OSX -> ["-q", "-s"]
_ -> ["-q"]
extraArgs = verbosityOpts verbosity ++ [target]
simple = programInvocation ar (simpleArgs ++ extraArgs)
initial = programInvocation ar (initialArgs ++ extraArgs)
middle = initial
final = programInvocation ar (finalArgs ++ extraArgs)
in sequence_
[ runProgramInvocation verbosity inv
| inv <- multiStageProgramInvocation
simple (initial, middle, final) files ]
where
verbosityOpts v | v >= deafening = ["-v"]
| v >= verbose = []
| otherwise = ["-c"]
-----------------------------------------------------------------------------
-- |
-- 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 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment