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