1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE RankNTypes #-}
3
4-----------------------------------------------------------------------------
5-- |
6-- Module      :  Distribution.Simple.Program.Strip
7--
8-- Maintainer  :  cabal-devel@haskell.org
9-- Portability :  portable
10--
11-- This module provides an library interface to the @strip@ program.
12
13module Distribution.Simple.Program.Strip (stripLib, stripExe)
14       where
15
16import Prelude ()
17import Distribution.Compat.Prelude
18
19import Distribution.Simple.Program
20import Distribution.Simple.Utils
21import Distribution.System
22import Distribution.Verbosity
23import Distribution.Version
24
25import System.FilePath             (takeBaseName)
26
27runStrip :: Verbosity -> ProgramDb -> FilePath -> [String] -> IO ()
28runStrip verbosity progDb path args =
29  case lookupProgram stripProgram progDb of
30    Just strip -> runProgram verbosity strip (args ++ [path])
31    Nothing    -> unless (buildOS == Windows) $
32                  -- Don't bother warning on windows, we don't expect them to
33                  -- have the strip program anyway.
34                  warn verbosity $ "Unable to strip executable or library '"
35                                   ++ (takeBaseName path)
36                                   ++ "' (missing the 'strip' program)"
37
38stripExe :: Verbosity -> Platform -> ProgramDb -> FilePath -> IO ()
39stripExe verbosity (Platform _arch os) progdb path =
40  runStrip verbosity progdb path args
41  where
42    args = case os of
43       OSX -> ["-x"] -- By default, stripping the ghc binary on at least
44                     -- some OS X installations causes:
45                     --     HSbase-3.0.o: unknown symbol `_environ'"
46                     -- The -x flag fixes that.
47       _   -> []
48
49stripLib :: Verbosity -> Platform -> ProgramDb -> FilePath -> IO ()
50stripLib verbosity (Platform arch os) progdb path = do
51  case os of
52    OSX -> -- '--strip-unneeded' is not supported on OS X, iOS, AIX, or
53           -- Solaris. See #1630.
54           return ()
55    IOS -> return ()
56    AIX -> return ()
57    Solaris -> return ()
58    Windows -> -- Stripping triggers a bug in 'strip.exe' for
59               -- libraries with lots identically named modules. See
60               -- #1784.
61               return()
62    Linux | arch == I386 ->
63      -- Versions of 'strip' on 32-bit Linux older than 2.18 are
64      -- broken. See #2339.
65      let okVersion = orLaterVersion (mkVersion [2,18])
66      in case programVersion =<< lookupProgram stripProgram progdb of
67          Just v | withinRange v okVersion ->
68            runStrip verbosity progdb path args
69          _ -> warn verbosity $ "Unable to strip library '"
70                                ++ (takeBaseName path)
71                                ++ "' (version of 'strip' too old; "
72                                ++ "requires >= 2.18 on 32-bit Linux)"
73    _   -> runStrip verbosity progdb path args
74  where
75    args = ["--strip-unneeded"]
76