[project @ 2001-10-26 00:53:27 by sof]
[ghc-hetmet.git] / ghc / compiler / main / DriverPipeline.hs
1 -----------------------------------------------------------------------------
2 --
3 -- GHC Driver
4 --
5 -- (c) Simon Marlow 2000
6 --
7 -----------------------------------------------------------------------------
8
9 #include "../includes/config.h"
10
11 module DriverPipeline (
12
13         -- interfaces for the batch-mode driver
14    GhcMode(..), getGhcMode, v_GhcMode,
15    genPipeline, runPipeline, pipeLoop,
16
17         -- interfaces for the compilation manager (interpreted/batch-mode)
18    preprocess, compile, CompResult(..),
19
20         -- batch-mode linking interface
21    doLink,
22         -- DLL building
23    doMkDLL
24   ) where
25
26 #include "HsVersions.h"
27
28 import Packages
29 import CmTypes
30 import GetImports
31 import DriverState
32 import DriverUtil
33 import DriverMkDepend
34 import DriverPhases
35 import DriverFlags
36 import SysTools         ( newTempName, addFilesToClean, getSysMan )
37 import qualified SysTools       
38 import HscMain
39 import Finder
40 import HscTypes
41 import Outputable
42 import Module
43 import ErrUtils
44 import CmdLineOpts
45 import Config
46 import Panic
47 import Util
48
49 import Time             ( getClockTime )
50 import Directory
51 import System
52 import IOExts
53 import Exception
54
55 import IO
56 import Monad
57 import Maybe
58
59 import PackedString
60 import MatchPS
61
62 -----------------------------------------------------------------------------
63 -- GHC modes of operation
64
65 modeFlag :: String -> Maybe GhcMode
66 modeFlag "-M"            = Just $ DoMkDependHS
67 modeFlag "--mk-dll"      = Just $ DoMkDLL
68 modeFlag "-E"            = Just $ StopBefore Hsc
69 modeFlag "-C"            = Just $ StopBefore HCc
70 modeFlag "-S"            = Just $ StopBefore As
71 modeFlag "-c"            = Just $ StopBefore Ln
72 modeFlag "--make"        = Just $ DoMake
73 modeFlag "--interactive" = Just $ DoInteractive
74 modeFlag _               = Nothing
75
76 getGhcMode :: [String]
77          -> IO ( [String]   -- rest of command line
78                , GhcMode
79                , String     -- "GhcMode" flag
80                )
81 getGhcMode flags 
82   = case my_partition modeFlag flags of
83         ([]   , rest) -> return (rest, DoLink,  "") -- default is to do linking
84         ([(flag,one)], rest) -> return (rest, one, flag)
85         (_    , _   ) -> 
86           throwDyn (UsageError 
87                 "only one of the flags -M, -E, -C, -S, -c, --make, --interactive, -mk-dll is allowed")
88
89 -----------------------------------------------------------------------------
90 -- genPipeline
91 --
92 -- Herein is all the magic about which phases to run in which order, whether
93 -- the intermediate files should be in TMPDIR or in the current directory,
94 -- what the suffix of the intermediate files should be, etc.
95
96 -- The following compilation pipeline algorithm is fairly hacky.  A
97 -- better way to do this would be to express the whole compilation as a
98 -- data flow DAG, where the nodes are the intermediate files and the
99 -- edges are the compilation phases.  This framework would also work
100 -- nicely if a haskell dependency generator was included in the
101 -- driver.
102
103 -- It would also deal much more cleanly with compilation phases that
104 -- generate multiple intermediates, (eg. hsc generates .hc, .hi, and
105 -- possibly stub files), where some of the output files need to be
106 -- processed further (eg. the stub files need to be compiled by the C
107 -- compiler).
108
109 -- A cool thing to do would then be to execute the data flow graph
110 -- concurrently, automatically taking advantage of extra processors on
111 -- the host machine.  For example, when compiling two Haskell files
112 -- where one depends on the other, the data flow graph would determine
113 -- that the C compiler from the first compilation can be overlapped
114 -- with the hsc compilation for the second file.
115
116 data IntermediateFileType
117   = Temporary
118   | Persistent
119   deriving (Eq, Show)
120
121 genPipeline
122    :: GhcMode            -- when to stop
123    -> String             -- "stop after" flag (for error messages)
124    -> Bool               -- True => output is persistent
125    -> HscLang            -- preferred output language for hsc
126    -> (FilePath, String) -- original filename & its suffix 
127    -> IO [              -- list of phases to run for this file
128              (Phase,
129               IntermediateFileType,  -- keep the output from this phase?
130               String)                -- output file suffix
131          ]      
132
133 genPipeline todo stop_flag persistent_output lang (filename,suffix)
134  = do
135    split      <- readIORef v_Split_object_files
136    mangle     <- readIORef v_Do_asm_mangling
137    keep_hc    <- readIORef v_Keep_hc_files
138    keep_il    <- readIORef v_Keep_il_files
139    keep_raw_s <- readIORef v_Keep_raw_s_files
140    keep_s     <- readIORef v_Keep_s_files
141    osuf       <- readIORef v_Object_suf
142    hcsuf      <- readIORef v_HC_suf
143
144    let
145    ----------- -----  ----   ---   --   --  -  -  -
146     start = startPhase suffix
147
148       -- special case for mkdependHS: .hspp files go through MkDependHS
149     start_phase | todo == DoMkDependHS && start == Hsc  = MkDependHS
150                 | otherwise = start
151
152     haskellish = haskellish_suffix suffix
153     cish = cish_suffix suffix
154
155        -- for a .hc file we need to force lang to HscC
156     real_lang | start_phase == HCc || start_phase == Mangle = HscC
157               | otherwise                                   = lang
158
159    let
160    ----------- -----  ----   ---   --   --  -  -  -
161     pipeline
162       | todo == DoMkDependHS = [ Unlit, Cpp, HsPp, MkDependHS ]
163
164       | haskellish = 
165        case real_lang of
166         HscC    | split && mangle -> [ Unlit, Cpp, HsPp, Hsc, HCc, Mangle, 
167                                         SplitMangle, SplitAs ]
168                 | mangle          -> [ Unlit, Cpp, HsPp, Hsc, HCc, Mangle, As ]
169                 | split           -> not_valid
170                 | otherwise       -> [ Unlit, Cpp, HsPp, Hsc, HCc, As ]
171
172         HscAsm  | split           -> [ Unlit, Cpp, HsPp, Hsc, SplitMangle, SplitAs ]
173                 | otherwise       -> [ Unlit, Cpp, HsPp, Hsc, As ]
174
175         HscJava | split           -> not_valid
176                 | otherwise       -> error "not implemented: compiling via Java"
177 #ifdef ILX
178         HscILX  | split           -> not_valid
179                 | otherwise       -> [ Unlit, Cpp, HsPp, Hsc, Ilx2Il, Ilasm ]
180 #endif
181         HscNothing                -> [ Unlit, Cpp, HsPp, Hsc ]
182
183       | cish      = [ Cc, As ]
184
185       | otherwise = [ ]  -- just pass this file through to the linker
186
187         -- ToDo: this is somewhat cryptic
188     not_valid = throwDyn (UsageError ("invalid option combination"))
189
190     stop_phase = case todo of 
191                         StopBefore As | split -> SplitAs
192 #ifdef ILX
193                                       | real_lang == HscILX -> Ilasm
194 #endif
195                         StopBefore phase      -> phase
196                         DoMkDependHS          -> Ln
197                         DoLink                -> Ln
198    ----------- -----  ----   ---   --   --  -  -  -
199
200         -- this shouldn't happen.
201    when (start_phase /= Ln && start_phase `notElem` pipeline)
202         (throwDyn (CmdLineError ("can't find starting phase for "
203                                  ++ filename)))
204         -- if we can't find the phase we're supposed to stop before,
205         -- something has gone wrong.  This test carefully avoids the
206         -- case where we aren't supposed to do any compilation, because the file
207         -- is already in linkable form (for example).
208    when (start_phase `elem` pipeline && 
209          (stop_phase /= Ln && stop_phase `notElem` pipeline))
210         (throwDyn (UsageError 
211                     ("flag " ++ stop_flag
212                      ++ " is incompatible with source file `" ++ filename ++ "'")))
213    let
214         -- .o and .hc suffixes can be overriden by command-line options:
215       myPhaseInputExt Ln  | Just s <- osuf  = s
216       myPhaseInputExt HCc | Just s <- hcsuf = s
217       myPhaseInputExt other                 = phaseInputExt other
218
219       annotatePipeline
220          :: [Phase]             -- raw pipeline
221          -> Phase               -- phase to stop before
222          -> [(Phase, IntermediateFileType, String{-file extension-})]
223       annotatePipeline []     _    = []
224       annotatePipeline (Ln:_) _    = []
225       annotatePipeline (phase:next_phase:ps) stop = 
226           (phase, keep_this_output, myPhaseInputExt next_phase)
227              : annotatePipeline (next_phase:ps) stop
228           where
229                 keep_this_output
230                      | next_phase == stop 
231                      = if persistent_output then Persistent else Temporary
232                      | otherwise
233                      = case next_phase of
234                              Ln -> Persistent
235                              Mangle | keep_raw_s -> Persistent
236                              As     | keep_s     -> Persistent
237                              HCc    | keep_hc    -> Persistent
238 #ifdef ILX
239                              Ilasm  | keep_il    -> Persistent
240 #endif
241                              _other              -> Temporary
242
243         -- add information about output files to the pipeline
244         -- the suffix on an output file is determined by the next phase
245         -- in the pipeline, so we add linking to the end of the pipeline
246         -- to force the output from the final phase to be a .o file.
247
248       annotated_pipeline = annotatePipeline (pipeline ++ [Ln]) stop_phase
249
250       phase_ne p (p1,_,_) = (p1 /= p)
251    ----------- -----  ----   ---   --   --  -  -  -
252
253    return (
254      takeWhile (phase_ne stop_phase ) $
255      dropWhile (phase_ne start_phase) $
256      annotated_pipeline
257     )
258
259
260 runPipeline
261   :: [ (Phase, IntermediateFileType, String) ] -- phases to run
262   -> (String,String)            -- input file
263   -> Bool                       -- doing linking afterward?
264   -> Bool                       -- take into account -o when generating output?
265   -> IO (String, String)        -- return final filename
266
267 runPipeline pipeline (input_fn,suffix) do_linking use_ofile
268   = pipeLoop pipeline (input_fn,suffix) do_linking use_ofile basename suffix
269   where (basename, _) = splitFilename input_fn
270
271 pipeLoop [] input_fn _ _ _ _ = return input_fn
272 pipeLoop (all_phases@((phase, keep, o_suffix):phases))
273         (input_fn,real_suff) do_linking use_ofile orig_basename orig_suffix
274   = do
275
276      output_fn <- outputFileName (null phases) keep o_suffix
277
278      mbCarryOn <- run_phase phase orig_basename orig_suffix
279                             input_fn output_fn 
280         -- sometimes we bail out early, eg. when the compiler's recompilation
281         -- checker has determined that recompilation isn't necessary.
282      case mbCarryOn of
283        Nothing -> do
284               let (_,keep,final_suffix) = last all_phases
285               ofile <- outputFileName True keep final_suffix
286               return (ofile, final_suffix)
287           -- carry on ...
288        Just fn -> 
289               {-
290                Notice that in order to keep the invariant that we can
291                determine a compilation pipeline's 'start phase' just
292                by looking at the input filename, the input filename
293                to the next stage/phase is associated here with the suffix
294                of the output file, *even* if it does not have that
295                suffix in reality.
296                
297                Why is this important? Because we may run a compilation
298                pipeline in stages (cf. Main.main.compileFile's two stages),
299                so when generating the next stage we need to be precise
300                about what kind of file (=> suffix) is given as input.
301
302                [Not having to generate a pipeline in stages seems like
303                 the right way to go, but I've punted on this for now --sof]
304                
305               -}
306               pipeLoop phases (fn, o_suffix) do_linking use_ofile
307                         orig_basename orig_suffix
308   where
309      outputFileName last_phase keep suffix
310         = do o_file <- readIORef v_Output_file
311              if last_phase && not do_linking && use_ofile && isJust o_file
312                then case o_file of 
313                        Just s  -> return s
314                        Nothing -> error "outputFileName"
315                else if keep == Persistent
316                            then odir_ify (orig_basename ++ '.':suffix)
317                            else newTempName suffix
318
319 run_phase :: Phase
320           -> String                -- basename of original input source
321           -> String                -- its extension
322           -> FilePath              -- name of file which contains the input to this phase.
323           -> FilePath              -- where to stick the result.
324           -> IO (Maybe FilePath)
325                   -- Nothing => stop the compilation pipeline
326                   -- Just fn => the result of this phase can be found in 'fn'
327                   --            (this can either be 'input_fn' or 'output_fn').
328 -------------------------------------------------------------------------------
329 -- Unlit phase 
330
331 run_phase Unlit _basename _suff input_fn output_fn
332   = do unlit_flags <- getOpts opt_L
333        -- The -h option passes the file name for unlit to put in a #line directive
334        SysTools.runUnlit (map SysTools.Option unlit_flags ++
335                           [ SysTools.Option     "-h"
336                           , SysTools.Option     input_fn
337                           , SysTools.FileOption "" input_fn
338                           , SysTools.FileOption "" output_fn
339                           ])
340        return (Just output_fn)
341
342 -------------------------------------------------------------------------------
343 -- Cpp phase 
344
345 run_phase Cpp basename suff input_fn output_fn
346   = do src_opts <- getOptionsFromSource input_fn
347        unhandled_flags <- processArgs dynamic_flags src_opts []
348        checkProcessArgsResult unhandled_flags basename suff
349
350        do_cpp <- dynFlag cppFlag
351        if not do_cpp then
352            -- no need to preprocess CPP, just pass input file along
353            -- to the next phase of the pipeline.
354           return (Just input_fn)
355         else do
356             hscpp_opts      <- getOpts opt_P
357             hs_src_cpp_opts <- readIORef v_Hs_source_cpp_opts
358
359             cmdline_include_paths <- readIORef v_Include_paths
360             pkg_include_dirs <- getPackageIncludePath
361             let include_paths = foldr (\ x xs -> "-I" : x : xs) []
362                                   (cmdline_include_paths ++ pkg_include_dirs)
363
364             verb <- getVerbFlag
365             (md_c_flags, _) <- machdepCCOpts
366
367             SysTools.runCpp ([SysTools.Option verb]
368                             ++ map SysTools.Option include_paths
369                             ++ map SysTools.Option hs_src_cpp_opts
370                             ++ map SysTools.Option hscpp_opts
371                             ++ map SysTools.Option md_c_flags
372                             ++ [ SysTools.Option     "-x"
373                                , SysTools.Option     "c"
374                                , SysTools.Option     input_fn
375         -- We hackily use Option instead of FileOption here, so that the file
376         -- name is not back-slashed on Windows.  cpp is capable of
377         -- dealing with / in filenames, so it works fine.  Furthermore
378         -- if we put in backslashes, cpp outputs #line directives
379         -- with *double* backslashes.   And that in turn means that
380         -- our error messages get double backslashes in them.
381         -- In due course we should arrange that the lexer deals
382         -- with these \\ escapes properly.
383                                , SysTools.Option     "-o"
384                                , SysTools.FileOption "" output_fn
385                                ])
386             return (Just output_fn)
387
388 -------------------------------------------------------------------------------
389 -- HsPp phase 
390 run_phase HsPp basename suff input_fn output_fn
391   = do src_opts <- getOptionsFromSource input_fn
392        unhandled_flags <- processArgs dynamic_flags src_opts []
393        checkProcessArgsResult unhandled_flags basename suff
394
395        let orig_fn = basename ++ '.':suff
396        do_pp   <- dynFlag ppFlag
397        if not do_pp then
398            -- no need to preprocess, just pass input file along
399            -- to the next phase of the pipeline.
400           return (Just input_fn)
401         else do
402             hspp_opts      <- getOpts opt_F
403             hs_src_pp_opts <- readIORef v_Hs_source_pp_opts
404             SysTools.runPp ( [ SysTools.Option     orig_fn
405                              , SysTools.Option     input_fn
406                              , SysTools.FileOption "" output_fn
407                              ] ++
408                              map SysTools.Option hs_src_pp_opts ++
409                              map SysTools.Option hspp_opts
410                            )
411             return (Just output_fn)
412
413 -----------------------------------------------------------------------------
414 -- MkDependHS phase
415
416 run_phase MkDependHS basename suff input_fn output_fn 
417  = do src <- readFile input_fn
418       let (import_sources, import_normals, _) = getImports src
419       let orig_fn = basename ++ '.':suff
420       deps_sources <- mapM (findDependency True  orig_fn) import_sources
421       deps_normals <- mapM (findDependency False orig_fn) import_normals
422       let deps = deps_sources ++ deps_normals
423
424       osuf_opt <- readIORef v_Object_suf
425       let osuf = case osuf_opt of
426                    Nothing -> phaseInputExt Ln
427                    Just s  -> s
428
429       extra_suffixes <- readIORef v_Dep_suffixes
430       let suffixes = osuf : map (++ ('_':osuf)) extra_suffixes
431           ofiles = map (\suf -> basename ++ '.':suf) suffixes
432
433       objs <- mapM odir_ify ofiles
434
435         -- Handle for file that accumulates dependencies 
436       hdl <- readIORef v_Dep_tmp_hdl
437
438         -- std dependency of the object(s) on the source file
439       hPutStrLn hdl (unwords objs ++ " : " ++ basename ++ '.':suff)
440
441       let genDep (dep, False {- not an hi file -}) = 
442              hPutStrLn hdl (unwords objs ++ " : " ++ dep)
443           genDep (dep, True  {- is an hi file -}) = do
444              hisuf <- readIORef v_Hi_suf
445              let dep_base = remove_suffix '.' dep
446                  deps = (dep_base ++ hisuf)
447                         : map (\suf -> dep_base ++ suf ++ '_':hisuf) extra_suffixes
448                   -- length objs should be == length deps
449              sequence_ (zipWith (\o d -> hPutStrLn hdl (o ++ " : " ++ d)) objs deps)
450
451       sequence_ (map genDep [ d | Just d <- deps ])
452       return (Just output_fn)
453
454 -- add the lines to dep_makefile:
455            -- always:
456                    -- this.o : this.hs
457
458            -- if the dependency is on something other than a .hi file:
459                    -- this.o this.p_o ... : dep
460            -- otherwise
461                    -- if the import is {-# SOURCE #-}
462                            -- this.o this.p_o ... : dep.hi-boot[-$vers]
463                            
464                    -- else
465                            -- this.o ...   : dep.hi
466                            -- this.p_o ... : dep.p_hi
467                            -- ...
468    
469            -- (where .o is $osuf, and the other suffixes come from
470            -- the cmdline -s options).
471    
472 -----------------------------------------------------------------------------
473 -- Hsc phase
474
475 -- Compilation of a single module, in "legacy" mode (_not_ under
476 -- the direction of the compilation manager).
477 run_phase Hsc basename suff input_fn output_fn
478   = do
479         
480   -- we add the current directory (i.e. the directory in which
481   -- the .hs files resides) to the import path, since this is
482   -- what gcc does, and it's probably what you want.
483         let current_dir = getdir basename
484         
485         paths <- readIORef v_Include_paths
486         writeIORef v_Include_paths (current_dir : paths)
487         
488   -- figure out which header files to #include in a generated .hc file
489         c_includes <- getPackageCIncludes
490         cmdline_includes <- dynFlag cmdlineHcIncludes -- -#include options
491
492         let cc_injects = unlines (map mk_include 
493                                  (c_includes ++ reverse cmdline_includes))
494             mk_include h_file = 
495                 case h_file of 
496                    '"':_{-"-} -> "#include "++h_file
497                    '<':_      -> "#include "++h_file
498                    _          -> "#include \""++h_file++"\""
499
500         writeIORef v_HCHeader cc_injects
501
502   -- gather the imports and module name
503         (srcimps,imps,mod_name) <- getImportsFromFile input_fn
504
505   -- build a ModuleLocation to pass to hscMain.
506         (mod, location')
507            <- mkHomeModuleLocn mod_name basename (basename ++ '.':suff)
508
509   -- take -ohi into account if present
510         ohi <- readIORef v_Output_hi
511         let location | Just fn <- ohi = location'{ ml_hi_file = fn }
512                      | otherwise      = location'
513
514   -- figure out if the source has changed, for recompilation avoidance.
515   -- only do this if we're eventually going to generate a .o file.
516   -- (ToDo: do when generating .hc files too?)
517   --
518   -- Setting source_unchanged to True means that M.o seems
519   -- to be up to date wrt M.hs; so no need to recompile unless imports have
520   -- changed (which the compiler itself figures out).
521   -- Setting source_unchanged to False tells the compiler that M.o is out of
522   -- date wrt M.hs (or M.o doesn't exist) so we must recompile regardless.
523         do_recomp   <- readIORef v_Recomp
524         todo        <- readIORef v_GhcMode
525         expl_o_file <- readIORef v_Output_file
526         let o_file = 
527                 case expl_o_file of
528                   Nothing -> unJust "source_unchanged" (ml_obj_file location)
529                   Just x  -> x
530         source_unchanged <- 
531           if not (do_recomp && ( todo == DoLink || todo == StopBefore Ln ))
532              then return False
533              else do t1 <- getModificationTime (basename ++ '.':suff)
534                      o_file_exists <- doesFileExist o_file
535                      if not o_file_exists
536                         then return False       -- Need to recompile
537                         else do t2 <- getModificationTime o_file
538                                 if t2 > t1
539                                   then return True
540                                   else return False
541
542   -- get the DynFlags
543         dyn_flags <- getDynFlags
544
545         let dyn_flags' = dyn_flags { hscOutName = output_fn,
546                                      hscStubCOutName = basename ++ "_stub.c",
547                                      hscStubHOutName = basename ++ "_stub.h",
548                                      extCoreName = basename ++ ".hcr" }
549
550   -- run the compiler!
551         pcs <- initPersistentCompilerState
552         result <- hscMain OneShot
553                           dyn_flags' mod
554                           location{ ml_hspp_file=Just input_fn }
555                           source_unchanged
556                           False
557                           Nothing        -- no iface
558                           emptyModuleEnv -- HomeSymbolTable
559                           emptyModuleEnv -- HomeIfaceTable
560                           pcs
561
562         case result of {
563
564             HscFail pcs -> throwDyn (PhaseFailed "hsc" (ExitFailure 1));
565
566             HscNoRecomp pcs details iface -> do { SysTools.touch "Touching object file" o_file
567                                                 ; return Nothing } ;
568
569             HscRecomp pcs details iface stub_h_exists stub_c_exists
570                       _maybe_interpreted_code -> do
571
572                             -- deal with stubs
573                             maybe_stub_o <- compileStub dyn_flags' stub_c_exists
574                             case maybe_stub_o of
575                               Nothing -> return ()
576                               Just stub_o -> add v_Ld_inputs stub_o
577                             case hscLang dyn_flags of
578                               HscNothing -> return Nothing
579                               _ -> return (Just output_fn)
580     }
581
582 -----------------------------------------------------------------------------
583 -- Cc phase
584
585 -- we don't support preprocessing .c files (with -E) now.  Doing so introduces
586 -- way too many hacks, and I can't say I've ever used it anyway.
587
588 run_phase cc_phase basename suff input_fn output_fn
589    | cc_phase == Cc || cc_phase == HCc
590    = do cc_opts              <- getOpts opt_c
591         cmdline_include_paths <- readIORef v_Include_paths
592
593         let hcc = cc_phase == HCc
594
595                 -- add package include paths even if we're just compiling
596                 -- .c files; this is the Value Add(TM) that using
597                 -- ghc instead of gcc gives you :)
598         pkg_include_dirs <- getPackageIncludePath
599         let include_paths = foldr (\ x xs -> "-I" : x : xs) []
600                               (cmdline_include_paths ++ pkg_include_dirs)
601
602         mangle <- readIORef v_Do_asm_mangling
603         (md_c_flags, md_regd_c_flags) <- machdepCCOpts
604
605         verb <- getVerbFlag
606
607         o2 <- readIORef v_minus_o2_for_C
608         let opt_flag | o2        = "-O2"
609                      | otherwise = "-O"
610
611         pkg_extra_cc_opts <- getPackageExtraCcOpts
612
613         split_objs <- readIORef v_Split_object_files
614         let split_opt | hcc && split_objs = [ "-DUSE_SPLIT_MARKERS" ]
615                       | otherwise         = [ ]
616
617         excessPrecision <- readIORef v_Excess_precision
618         SysTools.runCc ([ SysTools.Option "-x", SysTools.Option "c"
619                         , SysTools.FileOption "" input_fn
620                         , SysTools.Option "-o"
621                         , SysTools.FileOption "" output_fn
622                         ]
623                        ++ map SysTools.Option (
624                           md_c_flags
625                        ++ (if cc_phase == HCc && mangle
626                              then md_regd_c_flags
627                              else [])
628                        ++ [ verb, "-S", "-Wimplicit", opt_flag ]
629                        ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
630                        ++ cc_opts
631                        ++ split_opt
632                        ++ (if excessPrecision then [] else [ "-ffloat-store" ])
633                        ++ include_paths
634                        ++ pkg_extra_cc_opts
635                        ))
636         return (Just output_fn)
637
638         -- ToDo: postprocess the output from gcc
639
640 -----------------------------------------------------------------------------
641 -- Mangle phase
642
643 run_phase Mangle _basename _suff input_fn output_fn
644   = do mangler_opts <- getOpts opt_m
645        machdep_opts <- if (prefixMatch "i386" cTARGETPLATFORM)
646                        then do n_regs <- dynFlag stolen_x86_regs
647                                return [ show n_regs ]
648                        else return []
649
650        SysTools.runMangle (map SysTools.Option mangler_opts
651                           ++ [ SysTools.FileOption "" input_fn
652                              , SysTools.FileOption "" output_fn
653                              ]
654                           ++ map SysTools.Option machdep_opts)
655        return (Just output_fn)
656
657 -----------------------------------------------------------------------------
658 -- Splitting phase
659
660 run_phase SplitMangle _basename _suff input_fn output_fn
661   = do  -- tmp_pfx is the prefix used for the split .s files
662         -- We also use it as the file to contain the no. of split .s files (sigh)
663         split_s_prefix <- SysTools.newTempName "split"
664         let n_files_fn = split_s_prefix
665
666         SysTools.runSplit [ SysTools.FileOption "" input_fn
667                           , SysTools.FileOption "" split_s_prefix
668                           , SysTools.FileOption "" n_files_fn
669                           ]
670
671         -- Save the number of split files for future references
672         s <- readFile n_files_fn
673         let n_files = read s :: Int
674         writeIORef v_Split_info (split_s_prefix, n_files)
675
676         -- Remember to delete all these files
677         addFilesToClean [ split_s_prefix ++ "__" ++ show n ++ ".s"
678                         | n <- [1..n_files]]
679
680         return (Just output_fn)
681
682 -----------------------------------------------------------------------------
683 -- As phase
684
685 run_phase As _basename _suff input_fn output_fn
686   = do  as_opts               <- getOpts opt_a
687         cmdline_include_paths <- readIORef v_Include_paths
688
689         SysTools.runAs (map SysTools.Option as_opts
690                        ++ [ SysTools.Option ("-I" ++ p) | p <- cmdline_include_paths ]
691                        ++ [ SysTools.Option "-c"
692                           , SysTools.FileOption "" input_fn
693                           , SysTools.Option "-o"
694                           , SysTools.FileOption "" output_fn
695                           ])
696         return (Just output_fn)
697
698 run_phase SplitAs basename _suff _input_fn output_fn
699   = do  as_opts <- getOpts opt_a
700
701         (split_s_prefix, n) <- readIORef v_Split_info
702
703         odir <- readIORef v_Output_dir
704         let real_odir = case odir of
705                                 Nothing -> basename
706                                 Just d  -> d
707
708         let assemble_file n
709               = do  let input_s  = split_s_prefix ++ "__" ++ show n ++ ".s"
710                     let output_o = newdir real_odir 
711                                         (basename ++ "__" ++ show n ++ ".o")
712                     real_o <- osuf_ify output_o
713                     SysTools.runAs (map SysTools.Option as_opts ++
714                                     [ SysTools.Option "-c"
715                                     , SysTools.Option "-o"
716                                     , SysTools.FileOption "" real_o
717                                     , SysTools.FileOption "" input_s
718                                     ])
719         
720         mapM_ assemble_file [1..n]
721         return (Just output_fn)
722
723 #ifdef ILX
724 -----------------------------------------------------------------------------
725 -- Ilx2Il phase
726 -- Run ilx2il over the ILX output, getting an IL file
727
728 run_phase Ilx2Il _basename _suff input_fn output_fn
729   = do  ilx2il_opts <- getOpts opt_I
730         SysTools.runIlx2il (map SysTools.Option ilx2il_opts
731                            ++ [ SysTools.Option "--no-add-suffix-to-assembly",
732                                 SysTools.Option "mscorlib",
733                                 SysTools.Option "-o",
734                                 SysTools.FileOption "" output_fn,
735                                 SysTools.FileOption "" input_fn ])
736         return (Just output_fn)
737
738 -----------------------------------------------------------------------------
739 -- Ilasm phase
740 -- Run ilasm over the IL, getting a DLL
741
742 run_phase Ilasm _basename _suff input_fn output_fn
743   = do  ilasm_opts <- getOpts opt_i
744         SysTools.runIlasm (map SysTools.Option ilasm_opts
745                            ++ [ SysTools.Option "/QUIET",
746                                 SysTools.Option "/DLL",
747                                 SysTools.FileOption "/OUT=" output_fn,
748                                 SysTools.FileOption "" input_fn ])
749         return (Just output_fn)
750
751 #endif -- ILX
752
753 -----------------------------------------------------------------------------
754 -- MoveBinary sort-of-phase
755 -- After having produced a binary, move it somewhere else and generate a
756 -- wrapper script calling the binary. Currently, we need this only in 
757 -- a parallel way (i.e. in GUM), because PVM expects the binary in a
758 -- central directory.
759 -- This is called from doLink below, after linking. I haven't made it
760 -- a separate phase to minimise interfering with other modules, and
761 -- we don't need the generality of a phase (MoveBinary is always
762 -- done after linking and makes only sense in a parallel setup)   -- HWL
763
764 run_phase_MoveBinary input_fn
765   = do  
766         sysMan   <- getSysMan
767         pvm_root <- getEnv "PVM_ROOT"
768         pvm_arch <- getEnv "PVM_ARCH"
769         let 
770            pvm_executable_base = "=" ++ input_fn
771            pvm_executable = pvm_root ++ "/bin/" ++ pvm_arch ++ "/" ++ pvm_executable_base
772         -- nuke old binary; maybe use configur'ed names for cp and rm?
773         system ("rm -f " ++ pvm_executable)
774         -- move the newly created binary into PVM land
775         system ("cp -p " ++ input_fn ++ " " ++ pvm_executable)
776         -- generate a wrapper script for running a parallel prg under PVM
777         writeFile input_fn (mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan)
778         return True
779
780 -- generates a Perl skript starting a parallel prg under PVM
781 mk_pvm_wrapper_script :: String -> String -> String -> String
782 mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan = unlines $
783  [
784   "eval 'exec perl -S $0 ${1+\"$@\"}'", 
785   "  if $running_under_some_shell;",
786   "# =!=!=!=!=!=!=!=!=!=!=!",
787   "# This script is automatically generated: DO NOT EDIT!!!",
788   "# Generated by Glasgow Haskell Compiler",
789   "# ngoqvam choHbogh vaj' vIHoHnISbej !!!!",
790   "#",
791   "$pvm_executable      = '" ++ pvm_executable ++ "';",
792   "$pvm_executable_base = '" ++ pvm_executable_base ++ "';",
793   "$SysMan = '" ++ sysMan ++ "';",
794   "",
795   {- ToDo: add the magical shortcuts again iff we actually use them -- HWL
796   "# first, some magical shortcuts to run "commands" on the binary",
797   "# (which is hidden)",
798   "if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {",
799   "    local($cmd) = $1;",
800   "    system("$cmd $pvm_executable");",
801   "    exit(0); # all done",
802   "}", -}
803   "",
804   "# Now, run the real binary; process the args first",
805   "$ENV{'PE'} = $pvm_executable_base;", --  ++ pvm_executable_base,
806   "$debug = '';",
807   "$nprocessors = 0; # the default: as many PEs as machines in PVM config",
808   "@nonPVM_args = ();",
809   "$in_RTS_args = 0;",
810   "",
811   "args: while ($a = shift(@ARGV)) {",
812   "    if ( $a eq '+RTS' ) {",
813   "     $in_RTS_args = 1;",
814   "    } elsif ( $a eq '-RTS' ) {",
815   "     $in_RTS_args = 0;",
816   "    }",
817   "    if ( $a eq '-d' && $in_RTS_args ) {",
818   "     $debug = '-';",
819   "    } elsif ( $a =~ /^-qN(\\d+)/ && $in_RTS_args ) {",
820   "     $nprocessors = $1;",
821   "    } elsif ( $a =~ /^-qp(\\d+)/ && $in_RTS_args ) {",
822   "     $nprocessors = $1;",
823   "    } else {",
824   "     push(@nonPVM_args, $a);",
825   "    }",
826   "}",
827   "",
828   "local($return_val) = 0;",
829   "# Start the parallel execution by calling SysMan",
830   "system(\"$SysMan $debug $pvm_executable $nprocessors @nonPVM_args\");",
831   "$return_val = $?;",
832   "# ToDo: fix race condition moving files and flushing them!!",
833   "system(\"cp $ENV{'HOME'}/$pvm_executable_base.???.gr .\") if -f \"$ENV{'HOME'}/$pvm_executable_base.002.gr\";",
834   "exit($return_val);"
835  ]
836
837 -----------------------------------------------------------------------------
838 -- Complain about non-dynamic flags in OPTIONS pragmas
839
840 checkProcessArgsResult flags basename suff
841   = do when (not (null flags)) (throwDyn (ProgramError (
842            basename ++ "." ++ suff 
843            ++ ": static flags are not allowed in {-# OPTIONS #-} pragmas:\n\t" 
844            ++ unwords flags)) (ExitFailure 1))
845
846 -----------------------------------------------------------------------------
847 -- Linking
848
849 doLink :: [String] -> IO ()
850 doLink o_files = do
851     verb       <- getVerbFlag
852     static     <- readIORef v_Static
853     no_hs_main <- readIORef v_NoHsMain
854
855     o_file <- readIORef v_Output_file
856     let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
857
858     pkg_lib_paths <- getPackageLibraryPath
859     let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
860
861     lib_paths <- readIORef v_Library_paths
862     let lib_path_opts = map ("-L"++) lib_paths
863
864     pkg_libs <- getPackageLibraries
865     let imp          = if static then "" else "_imp"
866         pkg_lib_opts = map (\lib -> "-l" ++ lib ++ imp) pkg_libs
867
868     libs <- readIORef v_Cmdline_libraries
869     let lib_opts = map ("-l"++) (reverse libs)
870          -- reverse because they're added in reverse order from the cmd line
871
872     pkg_extra_ld_opts <- getPackageExtraLdOpts
873
874         -- probably _stub.o files
875     extra_ld_inputs <- readIORef v_Ld_inputs
876
877         -- opts from -optl-<blah>
878     extra_ld_opts <- getStaticOpts v_Opt_l
879
880     rts_pkg <- getPackageDetails ["rts"]
881     std_pkg <- getPackageDetails ["std"]
882     let extra_os = if static || no_hs_main
883                    then []
884                    else [ head (library_dirs (head rts_pkg)) ++ "/Main.dll_o",
885                           head (library_dirs (head std_pkg)) ++ "/PrelMain.dll_o" ]
886
887     (md_c_flags, _) <- machdepCCOpts
888     SysTools.runLink ( [ SysTools.Option verb
889                        , SysTools.Option "-o"
890                        , SysTools.FileOption "" output_fn
891                        ]
892                       ++ map SysTools.Option (
893                          md_c_flags
894                       ++ o_files
895                       ++ extra_os
896                       ++ extra_ld_inputs
897                       ++ lib_path_opts
898                       ++ lib_opts
899                       ++ pkg_lib_path_opts
900                       ++ pkg_lib_opts
901                       ++ pkg_extra_ld_opts
902                       ++ extra_ld_opts
903                       ++ if static && not no_hs_main then
904                             [ "-u", prefixUnderscore "PrelMain_mainIO_closure",
905                               "-u", prefixUnderscore "__stginit_PrelMain"] 
906                          else []))
907
908     -- parallel only: move binary to another dir -- HWL
909     ways_ <- readIORef v_Ways
910     when (WayPar `elem` ways_)
911          (do success <- run_phase_MoveBinary output_fn
912              if success then return ()
913                         else throwDyn (InstallationError ("cannot move binary to PVM dir")))
914
915 -----------------------------------------------------------------------------
916 -- Making a DLL (only for Win32)
917
918 doMkDLL :: [String] -> IO ()
919 doMkDLL o_files = do
920     verb       <- getVerbFlag
921     static     <- readIORef v_Static
922     no_hs_main <- readIORef v_NoHsMain
923
924     o_file <- readIORef v_Output_file
925     let output_fn = case o_file of { Just s -> s; Nothing -> "HSdll.dll"; }
926
927     pkg_lib_paths <- getPackageLibraryPath
928     let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
929
930     lib_paths <- readIORef v_Library_paths
931     let lib_path_opts = map ("-L"++) lib_paths
932
933     pkg_libs <- getPackageLibraries
934     let imp = if static then "" else "_imp"
935         pkg_lib_opts = map (\lib -> "-l" ++ lib ++ imp) pkg_libs
936
937     libs <- readIORef v_Cmdline_libraries
938     let lib_opts = map ("-l"++) (reverse libs)
939          -- reverse because they're added in reverse order from the cmd line
940
941     pkg_extra_ld_opts <- getPackageExtraLdOpts
942
943         -- probably _stub.o files
944     extra_ld_inputs <- readIORef v_Ld_inputs
945
946         -- opts from -optdll-<blah>
947     extra_ld_opts <- getStaticOpts v_Opt_dll
948
949     rts_pkg <- getPackageDetails ["rts"]
950     std_pkg <- getPackageDetails ["std"]
951
952     let extra_os = if static || no_hs_main
953                    then []
954                    else [ head (library_dirs (head rts_pkg)) ++ "/Main.dll_o",
955                           head (library_dirs (head std_pkg)) ++ "/PrelMain.dll_o" ]
956
957     (md_c_flags, _) <- machdepCCOpts
958     SysTools.runMkDLL
959          ([ SysTools.Option verb
960           , SysTools.Option "-o"
961           , SysTools.FileOption "" output_fn
962           ]
963          ++ map SysTools.Option (
964             md_c_flags
965          ++ o_files
966          ++ extra_os
967          ++ [ "--target=i386-mingw32" ]
968          ++ extra_ld_inputs
969          ++ lib_path_opts
970          ++ lib_opts
971          ++ pkg_lib_path_opts
972          ++ pkg_lib_opts
973          ++ pkg_extra_ld_opts
974          ++ (case findPS (packString (concat extra_ld_opts)) (packString "--def") of
975                Nothing -> [ "--export-all" ]
976                Just _  -> [ "" ])
977          ++ extra_ld_opts
978         ))
979
980 -----------------------------------------------------------------------------
981 -- Just preprocess a file, put the result in a temp. file (used by the
982 -- compilation manager during the summary phase).
983
984 preprocess :: FilePath -> IO FilePath
985 preprocess filename =
986   ASSERT(haskellish_src_file filename) 
987   do restoreDynFlags    -- Restore to state of last save
988      let fInfo = (filename, getFileSuffix filename)
989      pipeline <- genPipeline (StopBefore Hsc) ("preprocess") False 
990                              defaultHscLang fInfo
991      (fn,_)   <- runPipeline pipeline fInfo
992                              False{-no linking-} False{-no -o flag-}
993      return fn
994
995 -----------------------------------------------------------------------------
996 -- Compile a single module, under the control of the compilation manager.
997 --
998 -- This is the interface between the compilation manager and the
999 -- compiler proper (hsc), where we deal with tedious details like
1000 -- reading the OPTIONS pragma from the source file, and passing the
1001 -- output of hsc through the C compiler.
1002
1003 -- The driver sits between 'compile' and 'hscMain', translating calls
1004 -- to the former into calls to the latter, and results from the latter
1005 -- into results from the former.  It does things like preprocessing
1006 -- the .hs file if necessary, and compiling up the .stub_c files to
1007 -- generate Linkables.
1008
1009 -- NB.  No old interface can also mean that the source has changed.
1010
1011 compile :: GhciMode                -- distinguish batch from interactive
1012         -> ModSummary              -- summary, including source
1013         -> Bool                    -- True <=> source unchanged
1014         -> Bool                    -- True <=> have object
1015         -> Maybe ModIface          -- old interface, if available
1016         -> HomeSymbolTable         -- for home module ModDetails
1017         -> HomeIfaceTable          -- for home module Ifaces
1018         -> PersistentCompilerState -- persistent compiler state
1019         -> IO CompResult
1020
1021 data CompResult
1022    = CompOK   PersistentCompilerState   -- updated PCS
1023               ModDetails  -- new details (HST additions)
1024               ModIface    -- new iface   (HIT additions)
1025               (Maybe Linkable)
1026                        -- new code; Nothing => compilation was not reqd
1027                        -- (old code is still valid)
1028
1029    | CompErrs PersistentCompilerState   -- updated PCS
1030
1031
1032 compile ghci_mode summary source_unchanged have_object 
1033         old_iface hst hit pcs = do 
1034    dyn_flags <- restoreDynFlags         -- Restore to the state of the last save
1035
1036
1037    showPass dyn_flags 
1038         (showSDoc (text "Compiling" <+> ppr (name_of_summary summary)))
1039
1040    let verb       = verbosity dyn_flags
1041    let location   = ms_location summary
1042    let input_fn   = unJust "compile:hs" (ml_hs_file location) 
1043    let input_fnpp = unJust "compile:hspp" (ml_hspp_file location)
1044
1045    when (verb >= 2) (hPutStrLn stderr ("compile: input file " ++ input_fnpp))
1046
1047    opts <- getOptionsFromSource input_fnpp
1048    processArgs dynamic_flags opts []
1049    dyn_flags <- getDynFlags
1050
1051    let hsc_lang      = hscLang dyn_flags
1052        (basename, _) = splitFilename input_fn
1053        
1054    keep_hc <- readIORef v_Keep_hc_files
1055    keep_il <- readIORef v_Keep_il_files
1056    keep_s  <- readIORef v_Keep_s_files
1057
1058    output_fn <- 
1059         case hsc_lang of
1060            HscAsm  | keep_s    -> return (basename ++ '.':phaseInputExt As)
1061                    | otherwise -> newTempName (phaseInputExt As)
1062            HscC    | keep_hc   -> return (basename ++ '.':phaseInputExt HCc)
1063                    | otherwise -> newTempName (phaseInputExt HCc)
1064            HscJava             -> newTempName "java" -- ToDo
1065 #ifdef ILX
1066            HscILX  | keep_il   -> return (basename ++ '.':phaseInputExt Ilasm)
1067                    | otherwise -> newTempName (phaseInputExt Ilx2Il)    
1068 #endif
1069            HscInterpreted      -> return (error "no output file")
1070            HscNothing          -> return (error "no output file")
1071
1072    let dyn_flags' = dyn_flags { hscOutName = output_fn,
1073                                 hscStubCOutName = basename ++ "_stub.c",
1074                                 hscStubHOutName = basename ++ "_stub.h",
1075                                 extCoreName = basename ++ ".hcr" }
1076
1077    -- figure out which header files to #include in a generated .hc file
1078    c_includes <- getPackageCIncludes
1079    cmdline_includes <- dynFlag cmdlineHcIncludes -- -#include options
1080
1081    let cc_injects = unlines (map mk_include 
1082                                  (c_includes ++ reverse cmdline_includes))
1083        mk_include h_file = 
1084         case h_file of 
1085            '"':_{-"-} -> "#include "++h_file
1086            '<':_      -> "#include "++h_file
1087            _          -> "#include \""++h_file++"\""
1088
1089    writeIORef v_HCHeader cc_injects
1090
1091    -- -no-recomp should also work with --make
1092    do_recomp <- readIORef v_Recomp
1093    let source_unchanged' = source_unchanged && do_recomp
1094
1095    -- run the compiler
1096    hsc_result <- hscMain ghci_mode dyn_flags'
1097                          (ms_mod summary) location
1098                          source_unchanged' have_object old_iface hst hit pcs
1099
1100    case hsc_result of
1101       HscFail pcs -> return (CompErrs pcs)
1102
1103       HscNoRecomp pcs details iface -> return (CompOK pcs details iface Nothing)
1104
1105       HscRecomp pcs details iface
1106         stub_h_exists stub_c_exists maybe_interpreted_code -> do
1107            
1108            let 
1109            maybe_stub_o <- compileStub dyn_flags' stub_c_exists
1110            let stub_unlinked = case maybe_stub_o of
1111                                   Nothing -> []
1112                                   Just stub_o -> [ DotO stub_o ]
1113
1114            (hs_unlinked, unlinked_time) <-
1115              case hsc_lang of
1116
1117                 -- in interpreted mode, just return the compiled code
1118                 -- as our "unlinked" object.
1119                 HscInterpreted -> 
1120                     case maybe_interpreted_code of
1121 #ifdef GHCI
1122                        Just (bcos,itbl_env) -> do tm <- getClockTime 
1123                                                   return ([BCOs bcos itbl_env], tm)
1124 #endif
1125                        Nothing -> panic "compile: no interpreted code"
1126
1127                 -- we're in batch mode: finish the compilation pipeline.
1128                 _other -> do pipe <- genPipeline (StopBefore Ln) "" True 
1129                                         hsc_lang (output_fn, getFileSuffix output_fn)
1130                              -- runPipeline takes input_fn so it can split off 
1131                              -- the base name and use it as the base of 
1132                              -- the output object file.
1133                              let (basename, suffix) = splitFilename input_fn
1134                              (o_file,_) <- 
1135                                  pipeLoop pipe (output_fn, getFileSuffix output_fn)
1136                                                False False 
1137                                                basename suffix
1138                              o_time <- getModificationTime o_file
1139                              return ([DotO o_file], o_time)
1140
1141            let linkable = LM unlinked_time (moduleName (ms_mod summary)) 
1142                              (hs_unlinked ++ stub_unlinked)
1143
1144            return (CompOK pcs details iface (Just linkable))
1145
1146
1147 -----------------------------------------------------------------------------
1148 -- stub .h and .c files (for foreign export support)
1149
1150 compileStub dflags stub_c_exists
1151   | not stub_c_exists = return Nothing
1152   | stub_c_exists = do
1153         -- compile the _stub.c file w/ gcc
1154         let stub_c = hscStubCOutName dflags
1155         pipeline   <- genPipeline (StopBefore Ln) "" True defaultHscLang (stub_c,"c")
1156         (stub_o,_) <- runPipeline pipeline (stub_c,"c") False{-no linking-} 
1157                                   False{-no -o option-}
1158         return (Just stub_o)