Cabal-1.10.0.0: Distribution/Simple/Program/Ar.hs
-----------------------------------------------------------------------------
-- |
-- 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 = case buildOS of
OSX -> ["-r", "-s"]
_ -> ["-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"]