{-# LANGUAGE ScopedTypeVariables #-}
module SysTools.Tasks where
import Exception
import ErrUtils
import HscTypes
import DynFlags
import Outputable
import GHC.Platform
import Util
import Data.List
import System.IO
import System.Process
import GhcPrelude
import LlvmCodeGen.Base (LlvmVersion, llvmVersionStr, supportedLlvmVersion, parseLlvmVersion)
import SysTools.Process
import SysTools.Info
runUnlit :: DynFlags -> [Option] -> IO ()
runUnlit :: DynFlags -> [Option] -> IO ()
runUnlit DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"unlit" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let prog :: String
prog = DynFlags -> String
pgm_L DynFlags
dflags
opts :: [String]
opts = DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_L
DynFlags -> String -> String -> [Option] -> IO ()
runSomething DynFlags
dflags String
"Literate pre-processor" String
prog
((String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option [String]
opts [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args)
runCpp :: DynFlags -> [Option] -> IO ()
runCpp :: DynFlags -> [Option] -> IO ()
runCpp DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"cpp" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_P DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_P)
args2 :: [Option]
args2 = [String -> Option
Option String
"-Werror" | GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_WarnIsError DynFlags
dflags]
[Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [String -> Option
Option String
"-Wundef" | WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnCPPUndef DynFlags
dflags]
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"C pre-processor" String
p
([Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args2 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args) Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
runPp :: DynFlags -> [Option] -> IO ()
runPp :: DynFlags -> [Option] -> IO ()
runPp DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"pp" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let prog :: String
prog = DynFlags -> String
pgm_F DynFlags
dflags
opts :: [Option]
opts = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_F)
DynFlags -> String -> String -> [Option] -> IO ()
runSomething DynFlags
dflags String
"Haskell pre-processor" String
prog ([Option]
args [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
opts)
runCc :: Maybe ForeignSrcLang -> DynFlags -> [Option] -> IO ()
runCc :: Maybe ForeignSrcLang -> DynFlags -> [Option] -> IO ()
runCc Maybe ForeignSrcLang
mLanguage DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"cc" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let p :: String
p = DynFlags -> String
pgm_c DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option [String]
userOpts
args2 :: [Option]
args2 = [Option]
languageOptions [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe [(String, String)]
-> IO ()
runSomethingResponseFile DynFlags
dflags String -> String
cc_filter String
"C Compiler" String
p [Option]
args2 Maybe [(String, String)]
mb_env
where
cc_filter :: String -> String
cc_filter = [String] -> String
unlines ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
doFilter ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines
doFilter :: [String] -> [String]
doFilter = [([String], [String])] -> [String]
unChunkWarnings ([([String], [String])] -> [String])
-> ([String] -> [([String], [String])]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([String], [String])] -> [([String], [String])]
filterWarnings ([([String], [String])] -> [([String], [String])])
-> ([String] -> [([String], [String])])
-> [String]
-> [([String], [String])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String] -> [([String], [String])]
chunkWarnings []
chunkWarnings :: [String]
-> [String]
-> [([String], [String])]
chunkWarnings :: [String] -> [String] -> [([String], [String])]
chunkWarnings [String]
loc_stack [] = [([String]
loc_stack, [])]
chunkWarnings [String]
loc_stack [String]
xs
= case (String -> Bool) -> [String] -> ([String], [String])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break String -> Bool
loc_stack_start [String]
xs of
([String]
warnings, String
lss:[String]
xs') ->
case (String -> Bool) -> [String] -> ([String], [String])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span String -> Bool
loc_start_continuation [String]
xs' of
([String]
lsc, [String]
xs'') ->
([String]
loc_stack, [String]
warnings) ([String], [String])
-> [([String], [String])] -> [([String], [String])]
forall a. a -> [a] -> [a]
: [String] -> [String] -> [([String], [String])]
chunkWarnings (String
lss String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
lsc) [String]
xs''
([String], [String])
_ -> [([String]
loc_stack, [String]
xs)]
filterWarnings :: [([String], [String])] -> [([String], [String])]
filterWarnings :: [([String], [String])] -> [([String], [String])]
filterWarnings [] = []
filterWarnings (([String]
xs, []) : [([String], [String])]
zs) = ([String]
xs, []) ([String], [String])
-> [([String], [String])] -> [([String], [String])]
forall a. a -> [a] -> [a]
: [([String], [String])] -> [([String], [String])]
filterWarnings [([String], [String])]
zs
filterWarnings (([String]
xs, [String]
ys) : [([String], [String])]
zs) = case (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
wantedWarning [String]
ys of
[] -> [([String], [String])] -> [([String], [String])]
filterWarnings [([String], [String])]
zs
[String]
ys' -> ([String]
xs, [String]
ys') ([String], [String])
-> [([String], [String])] -> [([String], [String])]
forall a. a -> [a] -> [a]
: [([String], [String])] -> [([String], [String])]
filterWarnings [([String], [String])]
zs
unChunkWarnings :: [([String], [String])] -> [String]
unChunkWarnings :: [([String], [String])] -> [String]
unChunkWarnings [] = []
unChunkWarnings (([String]
xs, [String]
ys) : [([String], [String])]
zs) = [String]
xs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
ys [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [([String], [String])] -> [String]
unChunkWarnings [([String], [String])]
zs
loc_stack_start :: String -> Bool
loc_stack_start String
s = String
"In file included from " String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s
loc_start_continuation :: String -> Bool
loc_start_continuation String
s = String
" from " String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s
wantedWarning :: String -> Bool
wantedWarning String
w
| String
"warning: call-clobbered register used" String -> String -> Bool
`isContainedIn` String
w = Bool
False
| Bool
otherwise = Bool
True
([Option]
languageOptions, [String]
userOpts) = case Maybe ForeignSrcLang
mLanguage of
Maybe ForeignSrcLang
Nothing -> ([], [String]
userOpts_c)
Just ForeignSrcLang
language -> ([String -> Option
Option String
"-x", String -> Option
Option String
languageName], [String]
opts)
where
(String
languageName, [String]
opts) = case ForeignSrcLang
language of
ForeignSrcLang
LangC -> (String
"c", [String]
userOpts_c)
ForeignSrcLang
LangCxx -> (String
"c++", [String]
userOpts_cxx)
ForeignSrcLang
LangObjc -> (String
"objective-c", [String]
userOpts_c)
ForeignSrcLang
LangObjcxx -> (String
"objective-c++", [String]
userOpts_cxx)
ForeignSrcLang
LangAsm -> (String
"assembler", [])
ForeignSrcLang
RawObject -> (String
"c", [])
userOpts_c :: [String]
userOpts_c = DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_c
userOpts_cxx :: [String]
userOpts_cxx = DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_cxx
isContainedIn :: String -> String -> Bool
String
xs isContainedIn :: String -> String -> Bool
`isContainedIn` String
ys = (String -> Bool) -> [String] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (String
xs String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) (String -> [String]
forall a. [a] -> [[a]]
tails String
ys)
askLd :: DynFlags -> [Option] -> IO String
askLd :: DynFlags -> [Option] -> IO String
askLd DynFlags
dflags [Option]
args = DynFlags -> String -> IO String -> IO String
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"linker" (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_l DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_l)
args2 :: [Option]
args2 = [Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> String
-> String
-> [Option]
-> ([String] -> IO (ExitCode, String))
-> IO String
forall a.
DynFlags
-> String
-> String
-> [Option]
-> ([String] -> IO (ExitCode, a))
-> IO a
runSomethingWith DynFlags
dflags String
"gcc" String
p [Option]
args2 (([String] -> IO (ExitCode, String)) -> IO String)
-> ([String] -> IO (ExitCode, String)) -> IO String
forall a b. (a -> b) -> a -> b
$ \[String]
real_args ->
CreateProcess -> IO (ExitCode, String)
readCreateProcessWithExitCode' (String -> [String] -> CreateProcess
proc String
p [String]
real_args){ env :: Maybe [(String, String)]
env = Maybe [(String, String)]
mb_env }
runAs :: DynFlags -> [Option] -> IO ()
runAs :: DynFlags -> [Option] -> IO ()
runAs DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"as" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_a DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_a)
args2 :: [Option]
args2 = [Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Assembler" String
p [Option]
args2 Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
runLlvmOpt :: DynFlags -> [Option] -> IO ()
runLlvmOpt :: DynFlags -> [Option] -> IO ()
runLlvmOpt DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"opt" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_lo DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_lo)
DynFlags -> String -> String -> [Option] -> IO ()
runSomething DynFlags
dflags String
"LLVM Optimiser" String
p ([Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args0)
runLlvmLlc :: DynFlags -> [Option] -> IO ()
runLlvmLlc :: DynFlags -> [Option] -> IO ()
runLlvmLlc DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"llc" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_lc DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_lc)
DynFlags -> String -> String -> [Option] -> IO ()
runSomething DynFlags
dflags String
"LLVM Compiler" String
p ([Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args)
runClang :: DynFlags -> [Option] -> IO ()
runClang :: DynFlags -> [Option] -> IO ()
runClang DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"clang" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
clang,[Option]
_) = DynFlags -> (String, [Option])
pgm_lcc DynFlags
dflags
(String
_,[Option]
args0) = DynFlags -> (String, [Option])
pgm_a DynFlags
dflags
args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_a)
args2 :: [Option]
args2 = [Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
IO () -> (SomeException -> IO ()) -> IO ()
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
Exception.catch (do
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Clang (Assembler)" String
clang [Option]
args2 Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
)
(\(SomeException
err :: SomeException) -> do
DynFlags -> MsgDoc -> IO ()
errorMsg DynFlags
dflags (MsgDoc -> IO ()) -> MsgDoc -> IO ()
forall a b. (a -> b) -> a -> b
$
String -> MsgDoc
text (String
"Error running clang! you need clang installed to use the" String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" LLVM backend") MsgDoc -> MsgDoc -> MsgDoc
$+$
String -> MsgDoc
text String
"(or GHC tried to execute clang incorrectly)"
SomeException -> IO ()
forall e a. Exception e => e -> IO a
throwIO SomeException
err
)
figureLlvmVersion :: DynFlags -> IO (Maybe LlvmVersion)
figureLlvmVersion :: DynFlags -> IO (Maybe LlvmVersion)
figureLlvmVersion DynFlags
dflags = DynFlags
-> String -> IO (Maybe LlvmVersion) -> IO (Maybe LlvmVersion)
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"llc" (IO (Maybe LlvmVersion) -> IO (Maybe LlvmVersion))
-> IO (Maybe LlvmVersion) -> IO (Maybe LlvmVersion)
forall a b. (a -> b) -> a -> b
$ do
let (String
pgm,[Option]
opts) = DynFlags -> (String, [Option])
pgm_lc DynFlags
dflags
args :: [String]
args = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
forall a. [a] -> Bool
notNull ((Option -> String) -> [Option] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Option -> String
showOpt [Option]
opts)
args' :: [String]
args' = [String]
args [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"-version"]
IO (Maybe LlvmVersion)
-> (IOException -> IO (Maybe LlvmVersion))
-> IO (Maybe LlvmVersion)
forall a. IO a -> (IOException -> IO a) -> IO a
catchIO (do
(Handle
pin, Handle
pout, Handle
perr, ProcessHandle
_) <- String
-> [String]
-> Maybe String
-> Maybe [(String, String)]
-> IO (Handle, Handle, Handle, ProcessHandle)
runInteractiveProcess String
pgm [String]
args'
Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
forall a. Maybe a
Nothing
Handle -> Bool -> IO ()
hSetBinaryMode Handle
pout Bool
False
String
_ <- Handle -> IO String
hGetLine Handle
pout
String
vline <- Handle -> IO String
hGetLine Handle
pout
let mb_ver :: Maybe LlvmVersion
mb_ver = String -> Maybe LlvmVersion
parseLlvmVersion String
vline
Handle -> IO ()
hClose Handle
pin
Handle -> IO ()
hClose Handle
pout
Handle -> IO ()
hClose Handle
perr
Maybe LlvmVersion -> IO (Maybe LlvmVersion)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe LlvmVersion
mb_ver
)
(\IOException
err -> do
DynFlags -> Int -> MsgDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2
(String -> MsgDoc
text String
"Error (figuring out LLVM version):" MsgDoc -> MsgDoc -> MsgDoc
<+>
String -> MsgDoc
text (IOException -> String
forall a. Show a => a -> String
show IOException
err))
DynFlags -> MsgDoc -> IO ()
errorMsg DynFlags
dflags (MsgDoc -> IO ()) -> MsgDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ [MsgDoc] -> MsgDoc
vcat
[ String -> MsgDoc
text String
"Warning:", Int -> MsgDoc -> MsgDoc
nest Int
9 (MsgDoc -> MsgDoc) -> MsgDoc -> MsgDoc
forall a b. (a -> b) -> a -> b
$
String -> MsgDoc
text String
"Couldn't figure out LLVM version!" MsgDoc -> MsgDoc -> MsgDoc
$$
String -> MsgDoc
text (String
"Make sure you have installed LLVM " String -> String -> String
forall a. [a] -> [a] -> [a]
++
LlvmVersion -> String
llvmVersionStr LlvmVersion
supportedLlvmVersion) ]
Maybe LlvmVersion -> IO (Maybe LlvmVersion)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe LlvmVersion
forall a. Maybe a
Nothing)
runLink :: DynFlags -> [Option] -> IO ()
runLink :: DynFlags -> [Option] -> IO ()
runLink DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"linker" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
[Option]
linkargs <- LinkerInfo -> [Option]
neededLinkArgs (LinkerInfo -> [Option]) -> IO LinkerInfo -> IO [Option]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` DynFlags -> IO LinkerInfo
getLinkerInfo DynFlags
dflags
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_l DynFlags
dflags
optl_args :: [Option]
optl_args = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_l)
args2 :: [Option]
args2 = [Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
linkargs [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
optl_args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe [(String, String)]
-> IO ()
runSomethingResponseFile DynFlags
dflags String -> String
ld_filter String
"Linker" String
p [Option]
args2 Maybe [(String, String)]
mb_env
where
ld_filter :: String -> String
ld_filter = case (Platform -> OS
platformOS (DynFlags -> Platform
targetPlatform DynFlags
dflags)) of
OS
OSSolaris2 -> String -> String
sunos_ld_filter
OS
_ -> String -> String
forall a. a -> a
id
sunos_ld_filter :: String -> String
sunos_ld_filter :: String -> String
sunos_ld_filter = [String] -> String
unlines ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
sunos_ld_filter' ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines
sunos_ld_filter' :: [String] -> [String]
sunos_ld_filter' [String]
x = if ([String] -> Bool
undefined_found [String]
x Bool -> Bool -> Bool
&& [String] -> Bool
ld_warning_found [String]
x)
then ([String] -> [String]
ld_prefix [String]
x) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
ld_postfix [String]
x)
else [String]
x
breakStartsWith :: [a] -> [[a]] -> ([[a]], [[a]])
breakStartsWith [a]
x [[a]]
y = ([a] -> Bool) -> [[a]] -> ([[a]], [[a]])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break ([a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf [a]
x) [[a]]
y
ld_prefix :: [String] -> [String]
ld_prefix = ([String], [String]) -> [String]
forall a b. (a, b) -> a
fst (([String], [String]) -> [String])
-> ([String] -> ([String], [String])) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> ([String], [String])
forall a. Eq a => [a] -> [[a]] -> ([[a]], [[a]])
breakStartsWith String
"Undefined"
undefined_found :: [String] -> Bool
undefined_found = Bool -> Bool
not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([String] -> Bool) -> ([String] -> [String]) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String], [String]) -> [String]
forall a b. (a, b) -> b
snd (([String], [String]) -> [String])
-> ([String] -> ([String], [String])) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> ([String], [String])
forall a. Eq a => [a] -> [[a]] -> ([[a]], [[a]])
breakStartsWith String
"Undefined"
ld_warn_break :: [String] -> ([String], [String])
ld_warn_break = String -> [String] -> ([String], [String])
forall a. Eq a => [a] -> [[a]] -> ([[a]], [[a]])
breakStartsWith String
"ld: warning: symbol referencing errors"
ld_postfix :: [String] -> [String]
ld_postfix = [String] -> [String]
forall a. [a] -> [a]
tail ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String], [String]) -> [String]
forall a b. (a, b) -> b
snd (([String], [String]) -> [String])
-> ([String] -> ([String], [String])) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> ([String], [String])
ld_warn_break
ld_warning_found :: [String] -> Bool
ld_warning_found = Bool -> Bool
not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([String] -> Bool) -> ([String] -> [String]) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String], [String]) -> [String]
forall a b. (a, b) -> b
snd (([String], [String]) -> [String])
-> ([String] -> ([String], [String])) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> ([String], [String])
ld_warn_break
runLibtool :: DynFlags -> [Option] -> IO ()
runLibtool :: DynFlags -> [Option] -> IO ()
runLibtool DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"libtool" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
[Option]
linkargs <- LinkerInfo -> [Option]
neededLinkArgs (LinkerInfo -> [Option]) -> IO LinkerInfo -> IO [Option]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` DynFlags -> IO LinkerInfo
getLinkerInfo DynFlags
dflags
let args1 :: [Option]
args1 = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_l)
args2 :: [Option]
args2 = [String -> Option
Option String
"-static"] [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args1 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
linkargs
libtool :: String
libtool = DynFlags -> String
pgm_libtool DynFlags
dflags
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
args2
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Linker" String
libtool [Option]
args2 Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
runAr :: DynFlags -> Maybe FilePath -> [Option] -> IO ()
runAr :: DynFlags -> Maybe String -> [Option] -> IO ()
runAr DynFlags
dflags Maybe String
cwd [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"ar" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let ar :: String
ar = DynFlags -> String
pgm_ar DynFlags
dflags
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Ar" String
ar [Option]
args Maybe String
cwd Maybe [(String, String)]
forall a. Maybe a
Nothing
askAr :: DynFlags -> Maybe FilePath -> [Option] -> IO String
askAr :: DynFlags -> Maybe String -> [Option] -> IO String
askAr DynFlags
dflags Maybe String
mb_cwd [Option]
args = DynFlags -> String -> IO String -> IO String
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"ar" (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
let ar :: String
ar = DynFlags -> String
pgm_ar DynFlags
dflags
DynFlags
-> String
-> String
-> [Option]
-> ([String] -> IO (ExitCode, String))
-> IO String
forall a.
DynFlags
-> String
-> String
-> [Option]
-> ([String] -> IO (ExitCode, a))
-> IO a
runSomethingWith DynFlags
dflags String
"Ar" String
ar [Option]
args (([String] -> IO (ExitCode, String)) -> IO String)
-> ([String] -> IO (ExitCode, String)) -> IO String
forall a b. (a -> b) -> a -> b
$ \[String]
real_args ->
CreateProcess -> IO (ExitCode, String)
readCreateProcessWithExitCode' (String -> [String] -> CreateProcess
proc String
ar [String]
real_args){ cwd :: Maybe String
cwd = Maybe String
mb_cwd }
runRanlib :: DynFlags -> [Option] -> IO ()
runRanlib :: DynFlags -> [Option] -> IO ()
runRanlib DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"ranlib" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let ranlib :: String
ranlib = DynFlags -> String
pgm_ranlib DynFlags
dflags
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Ranlib" String
ranlib [Option]
args Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
forall a. Maybe a
Nothing
runMkDLL :: DynFlags -> [Option] -> IO ()
runMkDLL :: DynFlags -> [Option] -> IO ()
runMkDLL DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"mkdll" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let (String
p,[Option]
args0) = DynFlags -> (String, [Option])
pgm_dll DynFlags
dflags
args1 :: [Option]
args1 = [Option]
args0 [Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++ [Option]
args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv ([Option]
args0[Option] -> [Option] -> [Option]
forall a. [a] -> [a] -> [a]
++[Option]
args)
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Make DLL" String
p [Option]
args1 Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
runWindres :: DynFlags -> [Option] -> IO ()
runWindres :: DynFlags -> [Option] -> IO ()
runWindres DynFlags
dflags [Option]
args = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"windres" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let cc :: String
cc = DynFlags -> String
pgm_c DynFlags
dflags
cc_args :: [Option]
cc_args = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (Settings -> [String]
sOpt_c (DynFlags -> Settings
settings DynFlags
dflags))
windres :: String
windres = DynFlags -> String
pgm_windres DynFlags
dflags
opts :: [Option]
opts = (String -> Option) -> [String] -> [Option]
forall a b. (a -> b) -> [a] -> [b]
map String -> Option
Option (DynFlags -> (DynFlags -> [String]) -> [String]
forall a. DynFlags -> (DynFlags -> [a]) -> [a]
getOpts DynFlags
dflags DynFlags -> [String]
opt_windres)
quote :: String -> String
quote String
x = String
"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""
args' :: [Option]
args' =
String -> Option
Option (String
"--preprocessor=" String -> String -> String
forall a. [a] -> [a] -> [a]
++
[String] -> String
unwords ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
quote (String
cc String -> [String] -> [String]
forall a. a -> [a] -> [a]
:
(Option -> String) -> [Option] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Option -> String
showOpt [Option]
opts [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[String
"-E", String
"-xc", String
"-DRC_INVOKED"])))
Option -> [Option] -> [Option]
forall a. a -> [a] -> [a]
: String -> Option
Option String
"--use-temp-file"
Option -> [Option] -> [Option]
forall a. a -> [a] -> [a]
: [Option]
args
Maybe [(String, String)]
mb_env <- [Option] -> IO (Maybe [(String, String)])
getGccEnv [Option]
cc_args
DynFlags
-> (String -> String)
-> String
-> String
-> [Option]
-> Maybe String
-> Maybe [(String, String)]
-> IO ()
runSomethingFiltered DynFlags
dflags String -> String
forall a. a -> a
id String
"Windres" String
windres [Option]
args' Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
mb_env
touch :: DynFlags -> String -> String -> IO ()
touch :: DynFlags -> String -> String -> IO ()
touch DynFlags
dflags String
purpose String
arg = DynFlags -> String -> IO () -> IO ()
forall a. DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
"touch" (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
DynFlags -> String -> String -> [Option] -> IO ()
runSomething DynFlags
dflags String
purpose (DynFlags -> String
pgm_T DynFlags
dflags) [String -> String -> Option
FileOption String
"" String
arg]
traceToolCommand :: DynFlags -> String -> IO a -> IO a
traceToolCommand :: DynFlags -> String -> IO a -> IO a
traceToolCommand DynFlags
dflags String
tool = DynFlags -> MsgDoc -> (a -> ()) -> IO a -> IO a
forall (m :: * -> *) a.
MonadIO m =>
DynFlags -> MsgDoc -> (a -> ()) -> m a -> m a
withTiming
DynFlags
dflags (String -> MsgDoc
text (String -> MsgDoc) -> String -> MsgDoc
forall a b. (a -> b) -> a -> b
$ String
"systool:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tool) (() -> a -> ()
forall a b. a -> b -> a
const ())