--
-- GHC Driver
--
--- (c) Simon Marlow 2000
+-- (c) The University of Glasgow 2002
--
-----------------------------------------------------------------------------
module DriverPipeline (
-- interfaces for the batch-mode driver
- GhcMode(..), getGhcMode, v_GhcMode,
genPipeline, runPipeline, pipeLoop,
-- interfaces for the compilation manager (interpreted/batch-mode)
import Panic
import Util
+#ifdef GHCI
import Time ( getClockTime )
+#endif
import Directory
import System
import IOExts
import Maybe
import PackedString
-import MatchPS
-
------------------------------------------------------------------------------
--- GHC modes of operation
-
-modeFlag :: String -> Maybe GhcMode
-modeFlag "-M" = Just $ DoMkDependHS
-modeFlag "--mk-dll" = Just $ DoMkDLL
-modeFlag "-E" = Just $ StopBefore Hsc
-modeFlag "-C" = Just $ StopBefore HCc
-modeFlag "-S" = Just $ StopBefore As
-modeFlag "-c" = Just $ StopBefore Ln
-modeFlag "--make" = Just $ DoMake
-modeFlag "--interactive" = Just $ DoInteractive
-modeFlag _ = Nothing
-
-getGhcMode :: [String]
- -> IO ( [String] -- rest of command line
- , GhcMode
- , String -- "GhcMode" flag
- )
-getGhcMode flags
- = case my_partition modeFlag flags of
- ([] , rest) -> return (rest, DoLink, "") -- default is to do linking
- ([(flag,one)], rest) -> return (rest, one, flag)
- (_ , _ ) ->
- throwDyn (UsageError
- "only one of the flags -M, -E, -C, -S, -c, --make, --interactive, -mk-dll is allowed")
-----------------------------------------------------------------------------
-- genPipeline
split <- readIORef v_Split_object_files
mangle <- readIORef v_Do_asm_mangling
keep_hc <- readIORef v_Keep_hc_files
+#ifdef ILX
keep_il <- readIORef v_Keep_il_files
+ keep_ilx <- readIORef v_Keep_ilx_files
+#endif
keep_raw_s <- readIORef v_Keep_raw_s_files
keep_s <- readIORef v_Keep_s_files
osuf <- readIORef v_Object_suf
let
----------- ----- ---- --- -- -- - - -
- pipeline
- | todo == DoMkDependHS = [ Unlit, Cpp, HsPp, MkDependHS ]
+ pipeline = preprocess ++ compile
+
+ preprocess
+ | haskellish = [ Unlit, Cpp, HsPp ]
+ | otherwise = [ ]
+
+ compile
+ | todo == DoMkDependHS = [ MkDependHS ]
+
+ | cish = [ Cc, As ]
| haskellish =
case real_lang of
- HscC | split && mangle -> [ Unlit, Cpp, HsPp, Hsc, HCc, Mangle,
- SplitMangle, SplitAs ]
- | mangle -> [ Unlit, Cpp, HsPp, Hsc, HCc, Mangle, As ]
+ HscC | split && mangle -> [ Hsc, HCc, Mangle, SplitMangle, SplitAs ]
+ | mangle -> [ Hsc, HCc, Mangle, As ]
| split -> not_valid
- | otherwise -> [ Unlit, Cpp, HsPp, Hsc, HCc, As ]
+ | otherwise -> [ Hsc, HCc, As ]
- HscAsm | split -> [ Unlit, Cpp, HsPp, Hsc, SplitMangle, SplitAs ]
- | otherwise -> [ Unlit, Cpp, HsPp, Hsc, As ]
+ HscCore | split && mangle -> [ Hsc, HCc, Mangle, SplitMangle, SplitAs ]
+ | mangle -> [ Hsc, HCc, Mangle, As ]
+ | split -> not_valid
+ | otherwise -> [ Hsc, HCc, As ]
+
+ HscAsm | split -> [ Hsc, SplitMangle, SplitAs ]
+ | otherwise -> [ Hsc, As ]
HscJava | split -> not_valid
| otherwise -> error "not implemented: compiling via Java"
#ifdef ILX
HscILX | split -> not_valid
- | otherwise -> [ Unlit, Cpp, HsPp, Hsc, Ilx2Il, Ilasm ]
+ | otherwise -> [ Hsc, Ilx2Il, Ilasm ]
#endif
- HscNothing -> [ Unlit, Cpp, HsPp, Hsc ]
-
- | cish = [ Cc, As ]
+ HscNothing -> [ Hsc, HCc ] -- HCc is a dummy stop phase
| otherwise = [ ] -- just pass this file through to the linker
StopBefore phase -> phase
DoMkDependHS -> Ln
DoLink -> Ln
+ DoMkDLL -> Ln
----------- ----- ---- --- -- -- - - -
-- this shouldn't happen.
-- something has gone wrong. This test carefully avoids the
-- case where we aren't supposed to do any compilation, because the file
-- is already in linkable form (for example).
+-- hPutStrLn stderr (show ((start_phase `elem` pipeline,stop_phase /= Ln,stop_phase `notElem` pipeline), start_phase, stop_phase, pipeline,todo))
+-- hFlush stderr
when (start_phase `elem` pipeline &&
(stop_phase /= Ln && stop_phase `notElem` pipeline))
- (throwDyn (UsageError
- ("flag " ++ stop_flag
- ++ " is incompatible with source file `" ++ filename ++ "'")))
+ (do
+ throwDyn (UsageError
+ ("flag `" ++ stop_flag
+ ++ "' is incompatible with source file `"
+ ++ filename ++ "'" ++ show pipeline ++ show stop_phase)))
let
-- .o and .hc suffixes can be overriden by command-line options:
myPhaseInputExt Ln | Just s <- osuf = s
As | keep_s -> Persistent
HCc | keep_hc -> Persistent
#ifdef ILX
+ Ilx2Il | keep_ilx -> Persistent
Ilasm | keep_il -> Persistent
#endif
_other -> Temporary
hdl <- readIORef v_Dep_tmp_hdl
-- std dependency of the object(s) on the source file
- hPutStrLn hdl (unwords objs ++ " : " ++ basename ++ '.':suff)
+ hPutStrLn hdl (unwords (map escapeSpaces objs) ++ " : " ++
+ escapeSpaces (basename ++ '.':suff))
let genDep (dep, False {- not an hi file -}) =
- hPutStrLn hdl (unwords objs ++ " : " ++ dep)
+ hPutStrLn hdl (unwords (map escapeSpaces objs) ++ " : " ++
+ escapeSpaces dep)
genDep (dep, True {- is an hi file -}) = do
hisuf <- readIORef v_Hi_suf
let dep_base = remove_suffix '.' dep
deps = (dep_base ++ hisuf)
: map (\suf -> dep_base ++ suf ++ '_':hisuf) extra_suffixes
-- length objs should be == length deps
- sequence_ (zipWith (\o d -> hPutStrLn hdl (o ++ " : " ++ d)) objs deps)
+ sequence_ (zipWith (\o d -> hPutStrLn hdl (escapeSpaces o ++ " : " ++ escapeSpaces d)) objs deps)
sequence_ (map genDep [ d | Just d <- deps ])
return (Just output_fn)
-- (where .o is $osuf, and the other suffixes come from
-- the cmdline -s options).
+
-----------------------------------------------------------------------------
-- Hsc phase
do_recomp <- readIORef v_Recomp
todo <- readIORef v_GhcMode
expl_o_file <- readIORef v_Output_file
- let o_file =
- case expl_o_file of
- Nothing -> unJust "source_unchanged" (ml_obj_file location)
- Just x -> x
+
+ let o_file -- if the -o option is given and IT IS THE OBJECT FILE FOR
+ -- THIS COMPILATION, then use that to determine if the
+ -- source is unchanged.
+ | Just x <- expl_o_file, todo == StopBefore Ln = x
+ | otherwise = unJust "source_unchanged" (ml_obj_file location)
+
source_unchanged <-
if not (do_recomp && ( todo == DoLink || todo == StopBefore Ln ))
then return False
| otherwise = [ ]
excessPrecision <- readIORef v_Excess_precision
- SysTools.runCc ([ SysTools.Option "-x", SysTools.Option "c"
- , SysTools.FileOption "" input_fn
+
+ -- force the C compiler to interpret this file as C when
+ -- compiling .hc files, by adding the -x c option.
+ let langopt
+ | cc_phase == HCc = [ SysTools.Option "-x", SysTools.Option "c"]
+ | otherwise = [ ]
+
+ SysTools.runCc (langopt ++
+ [ SysTools.FileOption "" input_fn
, SysTools.Option "-o"
, SysTools.FileOption "" output_fn
]
odir <- readIORef v_Output_dir
let real_odir = case odir of
- Nothing -> basename
+ Nothing -> basename ++ "_split"
Just d -> d
let assemble_file n
-- Complain about non-dynamic flags in OPTIONS pragmas
checkProcessArgsResult flags basename suff
- = do when (not (null flags)) (throwDyn (ProgramError (
+ = do when (notNull flags) (throwDyn (ProgramError (
basename ++ "." ++ suff
++ ": static flags are not allowed in {-# OPTIONS #-} pragmas:\n\t"
++ unwords flags)) (ExitFailure 1))
++ pkg_extra_ld_opts
++ extra_ld_opts
++ if static && not no_hs_main then
- [ "-u", prefixUnderscore "PrelMain_mainIO_closure",
- "-u", prefixUnderscore "__stginit_PrelMain"]
+ [ "-u", prefixUnderscore "Main_zdmain_closure"]
else []))
-- parallel only: move binary to another dir -- HWL
++ pkg_lib_path_opts
++ pkg_lib_opts
++ pkg_extra_ld_opts
- ++ (case findPS (packString (concat extra_ld_opts)) (packString "--def") of
- Nothing -> [ "--export-all" ]
- Just _ -> [ "" ])
+ ++ (if "--def" `elem` (concatMap words extra_ld_opts)
+ then [ "" ]
+ else [ "--export-all" ])
++ extra_ld_opts
))
showPass dyn_flags
- (showSDoc (text "Compiling" <+> ppr (name_of_summary summary)))
+ (showSDoc (text "Compiling" <+> ppr (modSummaryName summary)))
let verb = verbosity dyn_flags
let location = ms_location summary
(basename, _) = splitFilename input_fn
keep_hc <- readIORef v_Keep_hc_files
+#ifdef ILX
keep_il <- readIORef v_Keep_il_files
+#endif
keep_s <- readIORef v_Keep_s_files
output_fn <-
HscRecomp pcs details iface
stub_h_exists stub_c_exists maybe_interpreted_code -> do
-
let
maybe_stub_o <- compileStub dyn_flags' stub_c_exists
let stub_unlinked = case maybe_stub_o of
o_time <- getModificationTime o_file
return ([DotO o_file], o_time)
- let linkable = LM unlinked_time (moduleName (ms_mod summary))
+ let linkable = LM unlinked_time (modSummaryName summary)
(hs_unlinked ++ stub_unlinked)
return (CompOK pcs details iface (Just linkable))