4f19cfab38d5ff2f98e5c55d506413bb035fbe69
[ghc-hetmet.git] / compiler / main / DriverPipeline.hs
1 -----------------------------------------------------------------------------
2 --
3 -- GHC Driver
4 --
5 -- (c) The University of Glasgow 2005
6 --
7 -----------------------------------------------------------------------------
8
9 module DriverPipeline (
10         -- Run a series of compilation steps in a pipeline, for a
11         -- collection of source files.
12    oneShot, compileFile,
13
14         -- Interfaces for the batch-mode driver
15    linkBinary,
16
17         -- Interfaces for the compilation manager (interpreted/batch-mode)
18    preprocess, 
19    compile, CompResult(..), 
20    link, 
21
22   ) where
23
24 #include "HsVersions.h"
25
26 import Packages
27 import HeaderInfo
28 import DriverPhases
29 import SysTools
30 import HscMain
31 import Finder
32 import HscTypes
33 import Outputable
34 import Module
35 import UniqFM           ( eltsUFM )
36 import ErrUtils
37 import DynFlags
38 import StaticFlags      ( v_Ld_inputs, opt_Static, opt_HardwireLibPaths, WayName(..) )
39 import Config
40 import Panic
41 import Util
42 import StringBuffer     ( hGetStringBuffer )
43 import BasicTypes       ( SuccessFlag(..) )
44 import Maybes           ( expectJust )
45 import ParserCoreUtils  ( getCoreModuleName )
46 import SrcLoc           ( unLoc )
47 import SrcLoc           ( Located(..) )
48
49 import Control.Exception as Exception
50 import Data.IORef       ( readIORef, writeIORef, IORef )
51 import GHC.Exts         ( Int(..) )
52 import System.Directory
53 import System.IO
54 import SYSTEM_IO_ERROR as IO
55 import Control.Monad
56 import Data.List        ( isSuffixOf )
57 import Data.Maybe
58 import System.Exit
59 import System.Environment
60
61 -- ---------------------------------------------------------------------------
62 -- Pre-process
63
64 -- Just preprocess a file, put the result in a temp. file (used by the
65 -- compilation manager during the summary phase).
66 --
67 -- We return the augmented DynFlags, because they contain the result
68 -- of slurping in the OPTIONS pragmas
69
70 preprocess :: DynFlags -> (FilePath, Maybe Phase) -> IO (DynFlags, FilePath)
71 preprocess dflags (filename, mb_phase) =
72   ASSERT2(isJust mb_phase || isHaskellSrcFilename filename, text filename) 
73   runPipeline anyHsc dflags (filename, mb_phase) 
74         Nothing Temporary Nothing{-no ModLocation-}
75
76 -- ---------------------------------------------------------------------------
77 -- Compile
78
79 -- Compile a single module, under the control of the compilation manager.
80 --
81 -- This is the interface between the compilation manager and the
82 -- compiler proper (hsc), where we deal with tedious details like
83 -- reading the OPTIONS pragma from the source file, and passing the
84 -- output of hsc through the C compiler.
85
86 -- NB.  No old interface can also mean that the source has changed.
87
88 compile :: HscEnv
89         -> ModSummary
90         -> Maybe Linkable       -- Just linkable <=> source unchanged
91         -> Maybe ModIface       -- Old interface, if available
92         -> Int -> Int
93         -> IO CompResult
94
95 data CompResult
96    = CompOK   ModDetails        -- New details
97               ModIface          -- New iface
98               (Maybe Linkable)  -- a Maybe, for the same reasons as hm_linkable
99
100    | CompErrs 
101
102
103 compile hsc_env mod_summary maybe_old_linkable old_iface mod_index nmods = do 
104
105    let dflags0     = ms_hspp_opts mod_summary
106        this_mod    = ms_mod mod_summary
107        src_flavour = ms_hsc_src mod_summary
108
109        have_object 
110                | Just l <- maybe_old_linkable, isObjectLinkable l = True
111                | otherwise = False
112
113    -- FIXME: We need to know whether or not we're recompiling the file. Move this to HscMain?
114    --showPass dflags0 ("Compiling " ++ showModMsg have_object mod_summary)
115
116    let location   = ms_location mod_summary
117    let input_fn   = expectJust "compile:hs" (ml_hs_file location) 
118    let input_fnpp = ms_hspp_file mod_summary
119
120    debugTraceMsg dflags0 2 (text "compile: input file" <+> text input_fnpp)
121
122    let (basename, _) = splitFilename input_fn
123
124   -- We add the directory in which the .hs files resides) to the import path.
125   -- This is needed when we try to compile the .hc file later, if it
126   -- imports a _stub.h file that we created here.
127    let current_dir = directoryOf basename
128        old_paths   = includePaths dflags0
129        dflags      = dflags0 { includePaths = current_dir : old_paths }
130
131    -- Figure out what lang we're generating
132    let hsc_lang = hscMaybeAdjustTarget dflags StopLn src_flavour (hscTarget dflags)
133    -- ... and what the next phase should be
134    let next_phase = hscNextPhase dflags src_flavour hsc_lang
135    -- ... and what file to generate the output into
136    output_fn <- getOutputFilename next_phase 
137                         Temporary basename dflags next_phase (Just location)
138
139    let dflags' = dflags { hscTarget = hsc_lang,
140                                 hscOutName = output_fn,
141                                 extCoreName = basename ++ ".hcr" }
142
143    -- -no-recomp should also work with --make
144    let force_recomp = dopt Opt_ForceRecomp dflags
145        source_unchanged = isJust maybe_old_linkable && not force_recomp
146        hsc_env' = hsc_env { hsc_dflags = dflags' }
147        object_filename = ml_obj_file location
148
149    let getStubLinkable False = return []
150        getStubLinkable True
151            = do stub_o <- compileStub dflags' this_mod location
152                 return [ DotO stub_o ]
153
154        handleBatch (HscNoRecomp, iface, details)
155            = ASSERT (isJust maybe_old_linkable)
156              return (CompOK details iface maybe_old_linkable)
157        handleBatch (HscRecomp hasStub, iface, details)
158            | isHsBoot src_flavour
159                = do SysTools.touch dflags' "Touching object file"
160                                    object_filename
161                     return (CompOK details iface Nothing)
162            | otherwise
163                = do stub_unlinked <- getStubLinkable hasStub
164                     (hs_unlinked, unlinked_time) <-
165                         case hsc_lang of
166                           HscNothing
167                             -> return ([], ms_hs_date mod_summary)
168                           -- We're in --make mode: finish the compilation pipeline.
169                           _other
170                             -> do runPipeline StopLn dflags (output_fn,Nothing)
171                                               (Just basename)
172                                               Persistent
173                                               (Just location)
174                                   -- The object filename comes from the ModLocation
175                                   o_time <- getModificationTime object_filename
176                                   return ([DotO object_filename], o_time)
177                     let linkable = LM unlinked_time this_mod
178                                    (hs_unlinked ++ stub_unlinked)
179                     return (CompOK details iface (Just linkable))
180
181        handleInterpreted (InteractiveNoRecomp, iface, details)
182            = ASSERT (isJust maybe_old_linkable)
183              return (CompOK details iface maybe_old_linkable)
184        handleInterpreted (InteractiveRecomp hasStub comp_bc, iface, details)
185            = do stub_unlinked <- getStubLinkable hasStub
186                 let hs_unlinked = [BCOs comp_bc]
187                     unlinked_time = ms_hs_date mod_summary
188                   -- Why do we use the timestamp of the source file here,
189                   -- rather than the current time?  This works better in
190                   -- the case where the local clock is out of sync
191                   -- with the filesystem's clock.  It's just as accurate:
192                   -- if the source is modified, then the linkable will
193                   -- be out of date.
194                 let linkable = LM unlinked_time this_mod
195                                (hs_unlinked ++ stub_unlinked)
196                 return (CompOK details iface (Just linkable))
197
198    let runCompiler compiler handle
199            = do mbResult <- compiler hsc_env' mod_summary
200                                      source_unchanged old_iface
201                                      (Just (mod_index, nmods))
202                 case mbResult of
203                   Nothing     -> return CompErrs
204                   Just result -> handle result
205    -- run the compiler
206    case hsc_lang of
207      HscInterpreted | not (isHsBoot src_flavour) -- We can't compile boot files to
208                                                  -- bytecode so don't even try.
209          -> runCompiler hscCompileInteractive handleInterpreted
210      HscNothing
211          -> runCompiler hscCompileNothing handleBatch
212      _other
213          -> runCompiler hscCompileBatch handleBatch
214
215 -----------------------------------------------------------------------------
216 -- stub .h and .c files (for foreign export support)
217
218 -- The _stub.c file is derived from the haskell source file, possibly taking
219 -- into account the -stubdir option.
220 --
221 -- Consequently, we derive the _stub.o filename from the haskell object
222 -- filename.  
223 --
224 -- This isn't necessarily the same as the object filename we
225 -- would get if we just compiled the _stub.c file using the pipeline.
226 -- For example:
227 --
228 --    ghc src/A.hs -odir obj
229 -- 
230 -- results in obj/A.o, and src/A_stub.c.  If we compile src/A_stub.c with
231 -- -odir obj, we would get obj/src/A_stub.o, which is wrong; we want
232 -- obj/A_stub.o.
233
234 compileStub :: DynFlags -> Module -> ModLocation -> IO FilePath
235 compileStub dflags mod location = do
236         let (o_base, o_ext) = splitFilename (ml_obj_file location)
237             stub_o = o_base ++ "_stub" `joinFileExt` o_ext
238
239         -- compile the _stub.c file w/ gcc
240         let (stub_c,_) = mkStubPaths dflags (moduleName mod) location
241         runPipeline StopLn dflags (stub_c,Nothing)  Nothing
242                 (SpecificFile stub_o) Nothing{-no ModLocation-}
243
244         return stub_o
245
246
247 -- ---------------------------------------------------------------------------
248 -- Link
249
250 link :: GhcLink                 -- interactive or batch
251      -> DynFlags                -- dynamic flags
252      -> Bool                    -- attempt linking in batch mode?
253      -> HomePackageTable        -- what to link
254      -> IO SuccessFlag
255
256 -- For the moment, in the batch linker, we don't bother to tell doLink
257 -- which packages to link -- it just tries all that are available.
258 -- batch_attempt_linking should only be *looked at* in batch mode.  It
259 -- should only be True if the upsweep was successful and someone
260 -- exports main, i.e., we have good reason to believe that linking
261 -- will succeed.
262
263 #ifdef GHCI
264 link LinkInMemory dflags batch_attempt_linking hpt
265     = do -- Not Linking...(demand linker will do the job)
266          return Succeeded
267 #endif
268
269 link NoLink dflags batch_attempt_linking hpt
270    = return Succeeded
271
272 link LinkBinary dflags batch_attempt_linking hpt
273    | batch_attempt_linking
274    = do 
275         let 
276             home_mod_infos = eltsUFM hpt
277
278             -- the packages we depend on
279             pkg_deps  = concatMap (dep_pkgs . mi_deps . hm_iface) home_mod_infos
280
281             -- the linkables to link
282             linkables = map (expectJust "link".hm_linkable) home_mod_infos
283
284         debugTraceMsg dflags 3 (text "link: linkables are ..." $$ vcat (map ppr linkables))
285
286         -- check for the -no-link flag
287         if isNoLink (ghcLink dflags)
288           then do debugTraceMsg dflags 3 (text "link(batch): linking omitted (-c flag given).")
289                   return Succeeded
290           else do
291
292         let getOfiles (LM _ _ us) = map nameOfObject (filter isObject us)
293             obj_files = concatMap getOfiles linkables
294
295             exe_file = exeFileName dflags
296
297         -- if the modification time on the executable is later than the
298         -- modification times on all of the objects, then omit linking
299         -- (unless the -no-recomp flag was given).
300         e_exe_time <- IO.try $ getModificationTime exe_file
301         let linking_needed 
302                 | Left _  <- e_exe_time = True
303                 | Right t <- e_exe_time = 
304                         any (t <) (map linkableTime linkables)
305
306         if not (dopt Opt_ForceRecomp dflags) && not linking_needed
307            then do debugTraceMsg dflags 2 (text exe_file <+> ptext SLIT("is up to date, linking not required."))
308                    return Succeeded
309            else do
310
311         debugTraceMsg dflags 1 (ptext SLIT("Linking") <+> text exe_file
312                                  <+> text "...")
313
314         -- Don't showPass in Batch mode; doLink will do that for us.
315         let link = case ghcLink dflags of
316                 LinkBinary  -> linkBinary
317                 LinkDynLib  -> linkDynLib
318         link dflags obj_files pkg_deps
319
320         debugTraceMsg dflags 3 (text "link: done")
321
322         -- linkBinary only returns if it succeeds
323         return Succeeded
324
325    | otherwise
326    = do debugTraceMsg dflags 3 (text "link(batch): upsweep (partially) failed OR" $$
327                                 text "   Main.main not exported; not linking.")
328         return Succeeded
329       
330 -- -----------------------------------------------------------------------------
331 -- Compile files in one-shot mode.
332
333 oneShot :: DynFlags -> Phase -> [(String, Maybe Phase)] -> IO ()
334 oneShot dflags stop_phase srcs = do
335   o_files <- mapM (compileFile dflags stop_phase) srcs
336   doLink dflags stop_phase o_files
337
338 compileFile :: DynFlags -> Phase -> (FilePath, Maybe Phase) -> IO FilePath
339 compileFile dflags stop_phase (src, mb_phase) = do
340    exists <- doesFileExist src
341    when (not exists) $ 
342         throwDyn (CmdLineError ("does not exist: " ++ src))
343    
344    let
345         split     = dopt Opt_SplitObjs dflags
346         mb_o_file = outputFile dflags
347         ghc_link  = ghcLink dflags      -- Set by -c or -no-link
348
349         -- When linking, the -o argument refers to the linker's output. 
350         -- otherwise, we use it as the name for the pipeline's output.
351         output
352          | StopLn <- stop_phase, not (isNoLink ghc_link) = Persistent
353                 -- -o foo applies to linker
354          | Just o_file <- mb_o_file = SpecificFile o_file
355                 -- -o foo applies to the file we are compiling now
356          | otherwise = Persistent
357
358         stop_phase' = case stop_phase of 
359                         As | split -> SplitAs
360                         other      -> stop_phase
361
362    (_, out_file) <- runPipeline stop_phase' dflags
363                           (src, mb_phase) Nothing output 
364                           Nothing{-no ModLocation-}
365    return out_file
366
367
368 doLink :: DynFlags -> Phase -> [FilePath] -> IO ()
369 doLink dflags stop_phase o_files
370   | not (isStopLn stop_phase)
371   = return ()           -- We stopped before the linking phase
372
373   | otherwise
374   = case ghcLink dflags of
375         NoLink     -> return ()
376         LinkBinary -> linkBinary dflags o_files link_pkgs
377         LinkDynLib -> linkDynLib dflags o_files []
378   where
379    -- Always link in the haskell98 package for static linking.  Other
380    -- packages have to be specified via the -package flag.
381     link_pkgs = [haskell98PackageId]
382
383
384 -- ---------------------------------------------------------------------------
385 -- Run a compilation pipeline, consisting of multiple phases.
386
387 -- This is the interface to the compilation pipeline, which runs
388 -- a series of compilation steps on a single source file, specifying
389 -- at which stage to stop.
390
391 -- The DynFlags can be modified by phases in the pipeline (eg. by
392 -- GHC_OPTIONS pragmas), and the changes affect later phases in the
393 -- pipeline.
394
395 data PipelineOutput 
396   = Temporary
397         -- output should be to a temporary file: we're going to
398         -- run more compilation steps on this output later
399   | Persistent
400         -- we want a persistent file, i.e. a file in the current directory
401         -- derived from the input filename, but with the appropriate extension.
402         -- eg. in "ghc -c Foo.hs" the output goes into ./Foo.o.
403   | SpecificFile FilePath
404         -- the output must go into the specified file.
405
406 runPipeline
407   :: Phase                      -- When to stop
408   -> DynFlags                   -- Dynamic flags
409   -> (FilePath,Maybe Phase)     -- Input filename (and maybe -x suffix)
410   -> Maybe FilePath             -- original basename (if different from ^^^)
411   -> PipelineOutput             -- Output filename
412   -> Maybe ModLocation          -- A ModLocation, if this is a Haskell module
413   -> IO (DynFlags, FilePath)    -- (final flags, output filename)
414
415 runPipeline stop_phase dflags (input_fn, mb_phase) mb_basename output maybe_loc
416   = do
417   let (input_basename, suffix) = splitFilename input_fn
418       basename | Just b <- mb_basename = b
419                | otherwise             = input_basename
420
421         -- If we were given a -x flag, then use that phase to start from
422       start_phase = fromMaybe (startPhase suffix) mb_phase
423
424   -- We want to catch cases of "you can't get there from here" before
425   -- we start the pipeline, because otherwise it will just run off the
426   -- end.
427   --
428   -- There is a partial ordering on phases, where A < B iff A occurs
429   -- before B in a normal compilation pipeline.
430
431   when (not (start_phase `happensBefore` stop_phase)) $
432         throwDyn (UsageError 
433                     ("cannot compile this file to desired target: "
434                        ++ input_fn))
435
436   -- this is a function which will be used to calculate output file names
437   -- as we go along (we partially apply it to some of its inputs here)
438   let get_output_fn = getOutputFilename stop_phase output basename
439
440   -- Execute the pipeline...
441   (dflags', output_fn, maybe_loc) <- 
442         pipeLoop dflags start_phase stop_phase input_fn 
443                  basename suffix get_output_fn maybe_loc
444
445   -- Sometimes, a compilation phase doesn't actually generate any output
446   -- (eg. the CPP phase when -fcpp is not turned on).  If we end on this
447   -- stage, but we wanted to keep the output, then we have to explicitly
448   -- copy the file, remembering to prepend a {-# LINE #-} pragma so that
449   -- further compilation stages can tell what the original filename was.
450   case output of
451     Temporary -> 
452         return (dflags', output_fn)
453     _other ->
454         do final_fn <- get_output_fn dflags' stop_phase maybe_loc
455            when (final_fn /= output_fn) $ do
456               let msg = ("Copying `" ++ output_fn ++"' to `" ++ final_fn ++ "'")
457                   line_prag = Just ("{-# LINE 1 \"" ++ input_fn ++ "\" #-}\n")
458               copyWithHeader dflags msg line_prag output_fn final_fn
459            return (dflags', final_fn)
460
461
462
463 pipeLoop :: DynFlags -> Phase -> Phase 
464          -> FilePath  -> String -> Suffix
465          -> (DynFlags -> Phase -> Maybe ModLocation -> IO FilePath)
466          -> Maybe ModLocation
467          -> IO (DynFlags, FilePath, Maybe ModLocation)
468
469 pipeLoop dflags phase stop_phase 
470          input_fn orig_basename orig_suff 
471          orig_get_output_fn maybe_loc
472
473   | phase `eqPhase` stop_phase            -- All done
474   = return (dflags, input_fn, maybe_loc)
475
476   | not (phase `happensBefore` stop_phase)
477         -- Something has gone wrong.  We'll try to cover all the cases when
478         -- this could happen, so if we reach here it is a panic.
479         -- eg. it might happen if the -C flag is used on a source file that
480         -- has {-# OPTIONS -fasm #-}.
481   = panic ("pipeLoop: at phase " ++ show phase ++ 
482            " but I wanted to stop at phase " ++ show stop_phase)
483
484   | otherwise 
485   = do  { (next_phase, dflags', maybe_loc, output_fn)
486                 <- runPhase phase stop_phase dflags orig_basename 
487                             orig_suff input_fn orig_get_output_fn maybe_loc
488         ; pipeLoop dflags' next_phase stop_phase output_fn
489                    orig_basename orig_suff orig_get_output_fn maybe_loc }
490
491 getOutputFilename
492   :: Phase -> PipelineOutput -> String
493   -> DynFlags -> Phase{-next phase-} -> Maybe ModLocation -> IO FilePath
494 getOutputFilename stop_phase output basename
495  = func
496  where
497         func dflags next_phase maybe_location
498            | is_last_phase, Persistent <- output     = persistent_fn
499            | is_last_phase, SpecificFile f <- output = return f
500            | keep_this_output                        = persistent_fn
501            | otherwise                               = newTempName dflags suffix
502            where
503                 hcsuf      = hcSuf dflags
504                 odir       = objectDir dflags
505                 osuf       = objectSuf dflags
506                 keep_hc    = dopt Opt_KeepHcFiles dflags
507                 keep_raw_s = dopt Opt_KeepRawSFiles dflags
508                 keep_s     = dopt Opt_KeepSFiles dflags
509
510                 myPhaseInputExt HCc    = hcsuf
511                 myPhaseInputExt StopLn = osuf
512                 myPhaseInputExt other  = phaseInputExt other
513
514                 is_last_phase = next_phase `eqPhase` stop_phase
515
516                 -- sometimes, we keep output from intermediate stages
517                 keep_this_output = 
518                      case next_phase of
519                              StopLn              -> True
520                              Mangle | keep_raw_s -> True
521                              As     | keep_s     -> True
522                              HCc    | keep_hc    -> True
523                              _other              -> False
524
525                 suffix = myPhaseInputExt next_phase
526
527                 -- persistent object files get put in odir
528                 persistent_fn 
529                    | StopLn <- next_phase = return odir_persistent
530                    | otherwise            = return persistent
531
532                 persistent = basename `joinFileExt` suffix
533
534                 odir_persistent
535                    | Just loc <- maybe_location = ml_obj_file loc
536                    | Just d <- odir = d `joinFileName` persistent
537                    | otherwise      = persistent
538
539
540 -- -----------------------------------------------------------------------------
541 -- Each phase in the pipeline returns the next phase to execute, and the
542 -- name of the file in which the output was placed.
543 --
544 -- We must do things dynamically this way, because we often don't know
545 -- what the rest of the phases will be until part-way through the
546 -- compilation: for example, an {-# OPTIONS -fasm #-} at the beginning
547 -- of a source file can change the latter stages of the pipeline from
548 -- taking the via-C route to using the native code generator.
549
550 runPhase :: Phase       -- Do this phase first
551          -> Phase       -- Stop just before this phase
552          -> DynFlags
553          -> String      -- basename of original input source
554          -> String      -- its extension
555          -> FilePath    -- name of file which contains the input to this phase.
556          -> (DynFlags -> Phase -> Maybe ModLocation -> IO FilePath)
557                         -- how to calculate the output filename
558          -> Maybe ModLocation           -- the ModLocation, if we have one
559          -> IO (Phase,                  -- next phase
560                 DynFlags,               -- new dynamic flags
561                 Maybe ModLocation,      -- the ModLocation, if we have one
562                 FilePath)               -- output filename
563
564         -- Invariant: the output filename always contains the output
565         -- Interesting case: Hsc when there is no recompilation to do
566         --                   Then the output filename is still a .o file 
567
568 -------------------------------------------------------------------------------
569 -- Unlit phase 
570
571 runPhase (Unlit sf) _stop dflags _basename _suff input_fn get_output_fn maybe_loc
572   = do let unlit_flags = getOpts dflags opt_L
573        -- The -h option passes the file name for unlit to put in a #line directive
574        output_fn <- get_output_fn dflags (Cpp sf) maybe_loc
575
576        SysTools.runUnlit dflags 
577                 (map SysTools.Option unlit_flags ++
578                           [ SysTools.Option     "-h"
579                           , SysTools.Option     input_fn
580                           , SysTools.FileOption "" input_fn
581                           , SysTools.FileOption "" output_fn
582                           ])
583
584        return (Cpp sf, dflags, maybe_loc, output_fn)
585
586 -------------------------------------------------------------------------------
587 -- Cpp phase : (a) gets OPTIONS out of file
588 --             (b) runs cpp if necessary
589
590 runPhase (Cpp sf) _stop dflags0 basename suff input_fn get_output_fn maybe_loc
591   = do src_opts <- getOptionsFromFile input_fn
592        (dflags,unhandled_flags) <- parseDynamicFlags dflags0 (map unLoc src_opts)
593        checkProcessArgsResult unhandled_flags (basename `joinFileExt` suff)
594
595        if not (dopt Opt_Cpp dflags) then
596            -- no need to preprocess CPP, just pass input file along
597            -- to the next phase of the pipeline.
598           return (HsPp sf, dflags, maybe_loc, input_fn)
599         else do
600             output_fn <- get_output_fn dflags (HsPp sf) maybe_loc
601             doCpp dflags True{-raw-} False{-no CC opts-} input_fn output_fn
602             return (HsPp sf, dflags, maybe_loc, output_fn)
603
604 -------------------------------------------------------------------------------
605 -- HsPp phase 
606
607 runPhase (HsPp sf) _stop dflags basename suff input_fn get_output_fn maybe_loc
608   = do if not (dopt Opt_Pp dflags) then
609            -- no need to preprocess, just pass input file along
610            -- to the next phase of the pipeline.
611           return (Hsc sf, dflags, maybe_loc, input_fn)
612         else do
613             let hspp_opts = getOpts dflags opt_F
614             let orig_fn = basename `joinFileExt` suff
615             output_fn <- get_output_fn dflags (Hsc sf) maybe_loc
616             SysTools.runPp dflags
617                            ( [ SysTools.Option     orig_fn
618                              , SysTools.Option     input_fn
619                              , SysTools.FileOption "" output_fn
620                              ] ++
621                              map SysTools.Option hspp_opts
622                            )
623             return (Hsc sf, dflags, maybe_loc, output_fn)
624
625 -----------------------------------------------------------------------------
626 -- Hsc phase
627
628 -- Compilation of a single module, in "legacy" mode (_not_ under
629 -- the direction of the compilation manager).
630 runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _maybe_loc 
631  = do   -- normal Hsc mode, not mkdependHS
632
633   -- we add the current directory (i.e. the directory in which
634   -- the .hs files resides) to the import path, since this is
635   -- what gcc does, and it's probably what you want.
636         let current_dir = directoryOf basename
637         
638             paths = includePaths dflags0
639             dflags = dflags0 { includePaths = current_dir : paths }
640         
641   -- gather the imports and module name
642         (hspp_buf,mod_name,imps,src_imps) <- 
643             case src_flavour of
644                 ExtCoreFile -> do {  -- no explicit imports in ExtCore input.
645                                   ; m <- getCoreModuleName input_fn
646                                   ; return (Nothing, mkModuleName m, [], []) }
647
648                 other -> do { buf <- hGetStringBuffer input_fn
649                             ; (src_imps,imps,L _ mod_name) <- getImports dflags buf input_fn
650                             ; return (Just buf, mod_name, imps, src_imps) }
651
652   -- Build a ModLocation to pass to hscMain.
653   -- The source filename is rather irrelevant by now, but it's used
654   -- by hscMain for messages.  hscMain also needs 
655   -- the .hi and .o filenames, and this is as good a way
656   -- as any to generate them, and better than most. (e.g. takes 
657   -- into accout the -osuf flags)
658         location1 <- mkHomeModLocation2 dflags mod_name basename suff
659
660   -- Boot-ify it if necessary
661         let location2 | isHsBoot src_flavour = addBootSuffixLocn location1
662                       | otherwise            = location1 
663                                         
664
665   -- Take -ohi into account if present
666   -- This can't be done in mkHomeModuleLocation because
667   -- it only applies to the module being compiles
668         let ohi = outputHi dflags
669             location3 | Just fn <- ohi = location2{ ml_hi_file = fn }
670                       | otherwise      = location2
671
672   -- Take -o into account if present
673   -- Very like -ohi, but we must *only* do this if we aren't linking
674   -- (If we're linking then the -o applies to the linked thing, not to
675   -- the object file for one module.)
676   -- Note the nasty duplication with the same computation in compileFile above
677         let expl_o_file = outputFile dflags
678             location4 | Just ofile <- expl_o_file
679                       , isNoLink (ghcLink dflags)
680                       = location3 { ml_obj_file = ofile }
681                       | otherwise = location3
682
683             o_file = ml_obj_file location4      -- The real object file
684
685
686   -- Figure out if the source has changed, for recompilation avoidance.
687   --
688   -- Setting source_unchanged to True means that M.o seems
689   -- to be up to date wrt M.hs; so no need to recompile unless imports have
690   -- changed (which the compiler itself figures out).
691   -- Setting source_unchanged to False tells the compiler that M.o is out of
692   -- date wrt M.hs (or M.o doesn't exist) so we must recompile regardless.
693         src_timestamp <- getModificationTime (basename `joinFileExt` suff)
694
695         let force_recomp = dopt Opt_ForceRecomp dflags
696         source_unchanged <- 
697           if force_recomp || not (isStopLn stop)
698                 -- Set source_unchanged to False unconditionally if
699                 --      (a) recompilation checker is off, or
700                 --      (b) we aren't going all the way to .o file (e.g. ghc -S)
701              then return False  
702                 -- Otherwise look at file modification dates
703              else do o_file_exists <- doesFileExist o_file
704                      if not o_file_exists
705                         then return False       -- Need to recompile
706                         else do t2 <- getModificationTime o_file
707                                 if t2 > src_timestamp
708                                   then return True
709                                   else return False
710
711   -- get the DynFlags
712         let hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
713         let next_phase = hscNextPhase dflags src_flavour hsc_lang
714         output_fn  <- get_output_fn dflags next_phase (Just location4)
715
716         let dflags' = dflags { hscTarget = hsc_lang,
717                                hscOutName = output_fn,
718                                extCoreName = basename ++ ".hcr" }
719
720         hsc_env <- newHscEnv dflags'
721
722   -- Tell the finder cache about this module
723         mod <- addHomeModuleToFinder hsc_env mod_name location4
724
725   -- Make the ModSummary to hand to hscMain
726         let
727             unused_field = panic "runPhase:ModSummary field"
728                 -- Some fields are not looked at by hscMain
729             mod_summary = ModSummary {  ms_mod       = mod, 
730                                         ms_hsc_src   = src_flavour,
731                                         ms_hspp_file = input_fn,
732                                         ms_hspp_opts = dflags,
733                                         ms_hspp_buf  = hspp_buf,
734                                         ms_location  = location4,
735                                         ms_hs_date   = src_timestamp,
736                                         ms_obj_date  = Nothing,
737                                         ms_imps      = imps,
738                                         ms_srcimps   = src_imps }
739
740   -- run the compiler!
741         mbResult <- hscCompileOneShot hsc_env
742                           mod_summary source_unchanged 
743                           Nothing       -- No iface
744                           Nothing       -- No "module i of n" progress info
745
746         case mbResult of
747           Nothing -> throwDyn (PhaseFailed "hsc" (ExitFailure 1))
748           Just HscNoRecomp
749               -> do SysTools.touch dflags' "Touching object file" o_file
750                     -- The .o file must have a later modification date
751                     -- than the source file (else we wouldn't be in HscNoRecomp)
752                     -- but we touch it anyway, to keep 'make' happy (we think).
753                     return (StopLn, dflags', Just location4, o_file)
754           Just (HscRecomp hasStub)
755               -> do when hasStub $
756                          do stub_o <- compileStub dflags' mod location4
757                             consIORef v_Ld_inputs stub_o
758                     -- In the case of hs-boot files, generate a dummy .o-boot 
759                     -- stamp file for the benefit of Make
760                     when (isHsBoot src_flavour) $
761                       SysTools.touch dflags' "Touching object file" o_file
762                     return (next_phase, dflags', Just location4, output_fn)
763
764 -----------------------------------------------------------------------------
765 -- Cmm phase
766
767 runPhase CmmCpp stop dflags basename suff input_fn get_output_fn maybe_loc
768   = do
769        output_fn <- get_output_fn dflags Cmm maybe_loc
770        doCpp dflags False{-not raw-} True{-include CC opts-} input_fn output_fn 
771        return (Cmm, dflags, maybe_loc, output_fn)
772
773 runPhase Cmm stop dflags basename suff input_fn get_output_fn maybe_loc
774   = do
775         let hsc_lang = hscMaybeAdjustTarget dflags stop HsSrcFile (hscTarget dflags)
776         let next_phase = hscNextPhase dflags HsSrcFile hsc_lang
777         output_fn <- get_output_fn dflags next_phase maybe_loc
778
779         let dflags' = dflags { hscTarget = hsc_lang,
780                                hscOutName = output_fn,
781                                extCoreName = basename ++ ".hcr" }
782
783         ok <- hscCmmFile dflags' input_fn
784
785         when (not ok) $ throwDyn (PhaseFailed "cmm" (ExitFailure 1))
786
787         return (next_phase, dflags, maybe_loc, output_fn)
788
789 -----------------------------------------------------------------------------
790 -- Cc phase
791
792 -- we don't support preprocessing .c files (with -E) now.  Doing so introduces
793 -- way too many hacks, and I can't say I've ever used it anyway.
794
795 runPhase cc_phase stop dflags basename suff input_fn get_output_fn maybe_loc
796    | cc_phase `eqPhase` Cc || cc_phase `eqPhase` Ccpp || cc_phase `eqPhase` HCc
797    = do let cc_opts = getOpts dflags opt_c
798             hcc = cc_phase `eqPhase` HCc
799
800         let cmdline_include_paths = includePaths dflags
801
802         -- HC files have the dependent packages stamped into them
803         pkgs <- if hcc then getHCFilePackages input_fn else return []
804
805         -- add package include paths even if we're just compiling .c
806         -- files; this is the Value Add(TM) that using ghc instead of
807         -- gcc gives you :)
808         pkg_include_dirs <- getPackageIncludePath dflags pkgs
809         let include_paths = foldr (\ x xs -> "-I" : x : xs) []
810                               (cmdline_include_paths ++ pkg_include_dirs)
811
812         let (md_c_flags, md_regd_c_flags) = machdepCCOpts dflags
813         gcc_extra_viac_flags <- getExtraViaCOpts dflags
814         let pic_c_flags = picCCOpts dflags
815
816         let verb = getVerbFlag dflags
817
818         pkg_extra_cc_opts <- getPackageExtraCcOpts dflags pkgs
819
820         let split_objs = dopt Opt_SplitObjs dflags
821             split_opt | hcc && split_objs = [ "-DUSE_SPLIT_MARKERS" ]
822                       | otherwise         = [ ]
823
824         let excessPrecision = dopt Opt_ExcessPrecision dflags
825
826         let cc_opt | optLevel dflags >= 2 = "-O2"
827                    | otherwise            = "-O"
828
829         -- Decide next phase
830         
831         let mangle = dopt Opt_DoAsmMangling dflags
832             next_phase
833                 | hcc && mangle     = Mangle
834                 | otherwise         = As
835         output_fn <- get_output_fn dflags next_phase maybe_loc
836
837         let
838           more_hcc_opts =
839 #if i386_TARGET_ARCH
840                 -- on x86 the floating point regs have greater precision
841                 -- than a double, which leads to unpredictable results.
842                 -- By default, we turn this off with -ffloat-store unless
843                 -- the user specified -fexcess-precision.
844                 (if excessPrecision then [] else [ "-ffloat-store" ]) ++
845 #endif
846                 -- gcc's -fstrict-aliasing allows two accesses to memory
847                 -- to be considered non-aliasing if they have different types.
848                 -- This interacts badly with the C code we generate, which is
849                 -- very weakly typed, being derived from C--.
850                 ["-fno-strict-aliasing"]
851
852
853
854         SysTools.runCc dflags (
855                 -- force the C compiler to interpret this file as C when
856                 -- compiling .hc files, by adding the -x c option.
857                 -- Also useful for plain .c files, just in case GHC saw a 
858                 -- -x c option.
859                         [ SysTools.Option "-x", if cc_phase `eqPhase` Ccpp
860                                                 then SysTools.Option "c++" else SysTools.Option "c"] ++
861                         [ SysTools.FileOption "" input_fn
862                         , SysTools.Option "-o"
863                         , SysTools.FileOption "" output_fn
864                         ]
865                        ++ map SysTools.Option (
866                           md_c_flags
867                        ++ pic_c_flags
868 #ifdef sparc_TARGET_ARCH
869         -- We only support SparcV9 and better because V8 lacks an atomic CAS
870         -- instruction. Note that the user can still override this
871         -- (e.g., -mcpu=ultrasparc) as GCC picks the "best" -mcpu flag
872         -- regardless of the ordering.
873         --
874         -- This is a temporary hack.
875                        ++ ["-mcpu=v9"]
876 #endif
877                        ++ (if hcc && mangle
878                              then md_regd_c_flags
879                              else [])
880                        ++ (if hcc
881                              then if mangle 
882                                      then gcc_extra_viac_flags
883                                      else filter (=="-fwrapv")
884                                                 gcc_extra_viac_flags
885                                 -- still want -fwrapv even for unreg'd
886                              else [])
887                        ++ (if hcc 
888                              then more_hcc_opts
889                              else [])
890                        ++ [ verb, "-S", "-Wimplicit", cc_opt ]
891                        ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
892                        ++ cc_opts
893                        ++ split_opt
894                        ++ include_paths
895                        ++ pkg_extra_cc_opts
896                        ))
897
898         return (next_phase, dflags, maybe_loc, output_fn)
899
900         -- ToDo: postprocess the output from gcc
901
902 -----------------------------------------------------------------------------
903 -- Mangle phase
904
905 runPhase Mangle stop dflags _basename _suff input_fn get_output_fn maybe_loc
906    = do let mangler_opts = getOpts dflags opt_m
907
908 #if i386_TARGET_ARCH
909         machdep_opts <- return [ show (stolen_x86_regs dflags) ]
910 #else
911         machdep_opts <- return []
912 #endif
913
914         let split = dopt Opt_SplitObjs dflags
915             next_phase
916                 | split = SplitMangle
917                 | otherwise = As
918         output_fn <- get_output_fn dflags next_phase maybe_loc
919
920         SysTools.runMangle dflags (map SysTools.Option mangler_opts
921                           ++ [ SysTools.FileOption "" input_fn
922                              , SysTools.FileOption "" output_fn
923                              ]
924                           ++ map SysTools.Option machdep_opts)
925
926         return (next_phase, dflags, maybe_loc, output_fn)
927
928 -----------------------------------------------------------------------------
929 -- Splitting phase
930
931 runPhase SplitMangle stop dflags _basename _suff input_fn get_output_fn maybe_loc
932   = do  -- tmp_pfx is the prefix used for the split .s files
933         -- We also use it as the file to contain the no. of split .s files (sigh)
934         split_s_prefix <- SysTools.newTempName dflags "split"
935         let n_files_fn = split_s_prefix
936
937         SysTools.runSplit dflags
938                           [ SysTools.FileOption "" input_fn
939                           , SysTools.FileOption "" split_s_prefix
940                           , SysTools.FileOption "" n_files_fn
941                           ]
942
943         -- Save the number of split files for future references
944         s <- readFile n_files_fn
945         let n_files = read s :: Int
946         writeIORef v_Split_info (split_s_prefix, n_files)
947
948         -- Remember to delete all these files
949         addFilesToClean [ split_s_prefix ++ "__" ++ show n ++ ".s"
950                         | n <- [1..n_files]]
951
952         return (SplitAs, dflags, maybe_loc, "**splitmangle**")
953           -- we don't use the filename
954
955 -----------------------------------------------------------------------------
956 -- As phase
957
958 runPhase As stop dflags _basename _suff input_fn get_output_fn maybe_loc
959   = do  let as_opts =  getOpts dflags opt_a
960         let cmdline_include_paths = includePaths dflags
961
962         output_fn <- get_output_fn dflags StopLn maybe_loc
963
964         -- we create directories for the object file, because it
965         -- might be a hierarchical module.
966         createDirectoryHierarchy (directoryOf output_fn)
967
968         SysTools.runAs dflags   
969                        (map SysTools.Option as_opts
970                        ++ [ SysTools.Option ("-I" ++ p) | p <- cmdline_include_paths ]
971 #ifdef sparc_TARGET_ARCH
972         -- We only support SparcV9 and better because V8 lacks an atomic CAS
973         -- instruction so we have to make sure that the assembler accepts the
974         -- instruction set. Note that the user can still override this
975         -- (e.g., -mcpu=ultrasparc). GCC picks the "best" -mcpu flag
976         -- regardless of the ordering.
977         --
978         -- This is a temporary hack.
979                        ++ [ SysTools.Option "-mcpu=v9" ]
980 #endif
981                        ++ [ SysTools.Option "-c"
982                           , SysTools.FileOption "" input_fn
983                           , SysTools.Option "-o"
984                           , SysTools.FileOption "" output_fn
985                           ])
986
987         return (StopLn, dflags, maybe_loc, output_fn)
988
989
990 runPhase SplitAs stop dflags basename _suff _input_fn get_output_fn maybe_loc
991   = do  
992         output_fn <- get_output_fn dflags StopLn maybe_loc
993
994         let (base_o, _) = splitFilename output_fn
995             split_odir  = base_o ++ "_split"
996             osuf = objectSuf dflags
997
998         createDirectoryHierarchy split_odir
999
1000         -- remove M_split/ *.o, because we're going to archive M_split/ *.o
1001         -- later and we don't want to pick up any old objects.
1002         fs <- getDirectoryContents split_odir 
1003         mapM_ removeFile $ map (split_odir `joinFileName`)
1004                          $ filter (osuf `isSuffixOf`) fs
1005
1006         let as_opts = getOpts dflags opt_a
1007
1008         (split_s_prefix, n) <- readIORef v_Split_info
1009
1010         let split_s   n = split_s_prefix ++ "__" ++ show n `joinFileExt` "s"
1011             split_obj n = split_odir `joinFileName`
1012                                 filenameOf base_o ++ "__" ++ show n
1013                                         `joinFileExt` osuf
1014
1015         let assemble_file n
1016               = SysTools.runAs dflags
1017                          (map SysTools.Option as_opts ++
1018                          [ SysTools.Option "-c"
1019                          , SysTools.Option "-o"
1020                          , SysTools.FileOption "" (split_obj n)
1021                          , SysTools.FileOption "" (split_s n)
1022                          ])
1023         
1024         mapM_ assemble_file [1..n]
1025
1026         -- and join the split objects into a single object file:
1027         let ld_r args = SysTools.runLink dflags ([ 
1028                                 SysTools.Option "-nostdlib",
1029                                 SysTools.Option "-nodefaultlibs",
1030                                 SysTools.Option "-Wl,-r", 
1031                                 SysTools.Option ld_x_flag, 
1032                                 SysTools.Option "-o", 
1033                                 SysTools.FileOption "" output_fn ] ++ args)
1034             ld_x_flag | null cLD_X = ""
1035                       | otherwise  = "-Wl,-x"     
1036
1037         if cLdIsGNULd == "YES"
1038             then do 
1039                   let script = split_odir `joinFileName` "ld.script"
1040                   writeFile script $
1041                       "INPUT(" ++ unwords (map split_obj [1..n]) ++ ")"
1042                   ld_r [SysTools.FileOption "" script]
1043             else do
1044                   ld_r (map (SysTools.FileOption "" . split_obj) [1..n])
1045
1046         return (StopLn, dflags, maybe_loc, output_fn)
1047
1048
1049 -----------------------------------------------------------------------------
1050 -- MoveBinary sort-of-phase
1051 -- After having produced a binary, move it somewhere else and generate a
1052 -- wrapper script calling the binary. Currently, we need this only in 
1053 -- a parallel way (i.e. in GUM), because PVM expects the binary in a
1054 -- central directory.
1055 -- This is called from linkBinary below, after linking. I haven't made it
1056 -- a separate phase to minimise interfering with other modules, and
1057 -- we don't need the generality of a phase (MoveBinary is always
1058 -- done after linking and makes only sense in a parallel setup)   -- HWL
1059
1060 runPhase_MoveBinary dflags input_fn
1061   = do  
1062         let sysMan = pgm_sysman dflags
1063         pvm_root <- getEnv "PVM_ROOT"
1064         pvm_arch <- getEnv "PVM_ARCH"
1065         let 
1066            pvm_executable_base = "=" ++ input_fn
1067            pvm_executable = pvm_root ++ "/bin/" ++ pvm_arch ++ "/" ++ pvm_executable_base
1068         -- nuke old binary; maybe use configur'ed names for cp and rm?
1069         Panic.try (removeFile pvm_executable)
1070         -- move the newly created binary into PVM land
1071         copy dflags "copying PVM executable" input_fn pvm_executable
1072         -- generate a wrapper script for running a parallel prg under PVM
1073         writeFile input_fn (mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan)
1074         return True
1075
1076 -- generates a Perl skript starting a parallel prg under PVM
1077 mk_pvm_wrapper_script :: String -> String -> String -> String
1078 mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan = unlines $
1079  [
1080   "eval 'exec perl -S $0 ${1+\"$@\"}'", 
1081   "  if $running_under_some_shell;",
1082   "# =!=!=!=!=!=!=!=!=!=!=!",
1083   "# This script is automatically generated: DO NOT EDIT!!!",
1084   "# Generated by Glasgow Haskell Compiler",
1085   "# ngoqvam choHbogh vaj' vIHoHnISbej !!!!",
1086   "#",
1087   "$pvm_executable      = '" ++ pvm_executable ++ "';",
1088   "$pvm_executable_base = '" ++ pvm_executable_base ++ "';",
1089   "$SysMan = '" ++ sysMan ++ "';",
1090   "",
1091   {- ToDo: add the magical shortcuts again iff we actually use them -- HWL
1092   "# first, some magical shortcuts to run "commands" on the binary",
1093   "# (which is hidden)",
1094   "if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {",
1095   "    local($cmd) = $1;",
1096   "    system("$cmd $pvm_executable");",
1097   "    exit(0); # all done",
1098   "}", -}
1099   "",
1100   "# Now, run the real binary; process the args first",
1101   "$ENV{'PE'} = $pvm_executable_base;", --  ++ pvm_executable_base,
1102   "$debug = '';",
1103   "$nprocessors = 0; # the default: as many PEs as machines in PVM config",
1104   "@nonPVM_args = ();",
1105   "$in_RTS_args = 0;",
1106   "",
1107   "args: while ($a = shift(@ARGV)) {",
1108   "    if ( $a eq '+RTS' ) {",
1109   "        $in_RTS_args = 1;",
1110   "    } elsif ( $a eq '-RTS' ) {",
1111   "        $in_RTS_args = 0;",
1112   "    }",
1113   "    if ( $a eq '-d' && $in_RTS_args ) {",
1114   "        $debug = '-';",
1115   "    } elsif ( $a =~ /^-qN(\\d+)/ && $in_RTS_args ) {",
1116   "        $nprocessors = $1;",
1117   "    } elsif ( $a =~ /^-qp(\\d+)/ && $in_RTS_args ) {",
1118   "        $nprocessors = $1;",
1119   "    } else {",
1120   "        push(@nonPVM_args, $a);",
1121   "    }",
1122   "}",
1123   "",
1124   "local($return_val) = 0;",
1125   "# Start the parallel execution by calling SysMan",
1126   "system(\"$SysMan $debug $pvm_executable $nprocessors @nonPVM_args\");",
1127   "$return_val = $?;",
1128   "# ToDo: fix race condition moving files and flushing them!!",
1129   "system(\"cp $ENV{'HOME'}/$pvm_executable_base.???.gr .\") if -f \"$ENV{'HOME'}/$pvm_executable_base.002.gr\";",
1130   "exit($return_val);"
1131  ]
1132
1133 -----------------------------------------------------------------------------
1134 -- Complain about non-dynamic flags in OPTIONS pragmas
1135
1136 checkProcessArgsResult flags filename
1137   = do when (notNull flags) (throwDyn (ProgramError (
1138           showSDoc (hang (text filename <> char ':')
1139                       4 (text "unknown flags in  {-# OPTIONS #-} pragma:" <+>
1140                           hsep (map text flags)))
1141         )))
1142
1143 -----------------------------------------------------------------------------
1144 -- Look for the /* GHC_PACKAGES ... */ comment at the top of a .hc file
1145
1146 getHCFilePackages :: FilePath -> IO [PackageId]
1147 getHCFilePackages filename =
1148   Exception.bracket (openFile filename ReadMode) hClose $ \h -> do
1149     l <- hGetLine h
1150     case l of
1151       '/':'*':' ':'G':'H':'C':'_':'P':'A':'C':'K':'A':'G':'E':'S':rest ->
1152           return (map stringToPackageId (words rest))
1153       _other ->
1154           return []
1155
1156 -----------------------------------------------------------------------------
1157 -- Static linking, of .o files
1158
1159 -- The list of packages passed to link is the list of packages on
1160 -- which this program depends, as discovered by the compilation
1161 -- manager.  It is combined with the list of packages that the user
1162 -- specifies on the command line with -package flags.  
1163 --
1164 -- In one-shot linking mode, we can't discover the package
1165 -- dependencies (because we haven't actually done any compilation or
1166 -- read any interface files), so the user must explicitly specify all
1167 -- the packages.
1168
1169 linkBinary :: DynFlags -> [FilePath] -> [PackageId] -> IO ()
1170 linkBinary dflags o_files dep_packages = do
1171     let verb = getVerbFlag dflags
1172         output_fn = exeFileName dflags
1173
1174     -- get the full list of packages to link with, by combining the
1175     -- explicit packages with the auto packages and all of their
1176     -- dependencies, and eliminating duplicates.
1177
1178     pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
1179     let pkg_lib_path_opts = concat (map get_pkg_lib_path_opts pkg_lib_paths)
1180         get_pkg_lib_path_opts l | opt_HardwireLibPaths && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
1181                                 | otherwise = ["-L" ++ l]
1182
1183     let lib_paths = libraryPaths dflags
1184     let lib_path_opts = map ("-L"++) lib_paths
1185
1186     pkg_link_opts <- getPackageLinkOpts dflags dep_packages
1187
1188 #ifdef darwin_TARGET_OS
1189     pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages
1190     let pkg_framework_path_opts = map ("-F"++) pkg_framework_paths
1191
1192     let framework_paths = frameworkPaths dflags
1193         framework_path_opts = map ("-F"++) framework_paths
1194
1195     pkg_frameworks <- getPackageFrameworks dflags dep_packages
1196     let pkg_framework_opts = concat [ ["-framework", fw] | fw <- pkg_frameworks ]
1197     
1198     let frameworks = cmdlineFrameworks dflags
1199         framework_opts = concat [ ["-framework", fw] | fw <- reverse frameworks ]
1200          -- reverse because they're added in reverse order from the cmd line
1201 #endif
1202
1203         -- probably _stub.o files
1204     extra_ld_inputs <- readIORef v_Ld_inputs
1205
1206         -- opts from -optl-<blah> (including -l<blah> options)
1207     let extra_ld_opts = getOpts dflags opt_l
1208
1209     let ways = wayNames dflags
1210
1211     -- Here are some libs that need to be linked at the *end* of
1212     -- the command line, because they contain symbols that are referred to
1213     -- by the RTS.  We can't therefore use the ordinary way opts for these.
1214     let
1215         debug_opts | WayDebug `elem` ways = [ 
1216 #if defined(HAVE_LIBBFD)
1217                         "-lbfd", "-liberty"
1218 #endif
1219                          ]
1220                    | otherwise            = []
1221
1222     let
1223         thread_opts | WayThreaded `elem` ways = [ 
1224 #if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS)
1225                         "-lpthread"
1226 #endif
1227 #if defined(osf3_TARGET_OS)
1228                         , "-lexc"
1229 #endif
1230                         ]
1231                     | otherwise               = []
1232
1233     rc_objs <- maybeCreateManifest dflags output_fn
1234
1235     let (md_c_flags, _) = machdepCCOpts dflags
1236     SysTools.runLink dflags ( 
1237                        [ SysTools.Option verb
1238                        , SysTools.Option "-o"
1239                        , SysTools.FileOption "" output_fn
1240                        ]
1241                       ++ map SysTools.Option (
1242                          md_c_flags
1243                       ++ o_files
1244                       ++ extra_ld_inputs
1245                       ++ lib_path_opts
1246                       ++ extra_ld_opts
1247                       ++ rc_objs
1248 #ifdef darwin_TARGET_OS
1249                       ++ framework_path_opts
1250                       ++ framework_opts
1251 #endif
1252                       ++ pkg_lib_path_opts
1253                       ++ pkg_link_opts
1254 #ifdef darwin_TARGET_OS
1255                       ++ pkg_framework_path_opts
1256                       ++ pkg_framework_opts
1257 #endif
1258                       ++ debug_opts
1259                       ++ thread_opts
1260                     ))
1261
1262     -- parallel only: move binary to another dir -- HWL
1263     when (WayPar `elem` ways)
1264          (do success <- runPhase_MoveBinary dflags output_fn
1265              if success then return ()
1266                         else throwDyn (InstallationError ("cannot move binary to PVM dir")))
1267
1268
1269 exeFileName :: DynFlags -> FilePath
1270 exeFileName dflags
1271   | Just s <- outputFile dflags = 
1272 #if defined(mingw32_HOST_OS)
1273       if null (suffixOf s)
1274         then s `joinFileExt` "exe"
1275         else s
1276 #else
1277       s
1278 #endif
1279   | otherwise = 
1280 #if defined(mingw32_HOST_OS)
1281         "main.exe"
1282 #else
1283         "a.out"
1284 #endif
1285
1286 maybeCreateManifest
1287    :: DynFlags
1288    -> FilePath                          -- filename of executable
1289    -> IO [FilePath]                     -- extra objects to embed, maybe
1290 maybeCreateManifest dflags exe_filename = do
1291 #ifndef mingw32_TARGET_OS
1292   return []
1293 #else
1294   if not (dopt Opt_GenManifest dflags) then return [] else do
1295
1296   let manifest_filename = exe_filename `joinFileExt` "manifest"
1297
1298   writeFile manifest_filename $ 
1299       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"++
1300       "  <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"++
1301       "  <assemblyIdentity version=\"1.0.0.0\"\n"++
1302       "     processorArchitecture=\"X86\"\n"++
1303       "     name=\"" ++ basenameOf exe_filename ++ "\"\n"++
1304       "     type=\"win32\"/>\n\n"++
1305       "  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n"++
1306       "    <security>\n"++
1307       "      <requestedPrivileges>\n"++
1308       "        <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n"++
1309       "        </requestedPrivileges>\n"++
1310       "       </security>\n"++
1311       "  </trustInfo>\n"++
1312       "</assembly>\n"
1313
1314   -- Windows will fine the manifest file if it is named foo.exe.manifest.
1315   -- However, for extra robustness, and so that we can move the binary around,
1316   -- we can embed the manifest in the binary itself using windres:
1317   if not (dopt Opt_EmbedManifest dflags) then return [] else do
1318
1319   rc_filename <- newTempName dflags "rc"
1320   rc_obj_filename <- newTempName dflags (objectSuf dflags)
1321
1322   writeFile rc_filename $
1323       "1 24 MOVEABLE PURE \"" ++ manifest_filename ++ "\"\n"
1324         -- magic numbers :-)
1325
1326   let wr_opts = getOpts dflags opt_windres
1327   runWindres dflags $ map SysTools.Option $
1328         ["--input="++rc_filename, 
1329          "--output="++rc_obj_filename,
1330          "--output-format=coff"] 
1331         ++ wr_opts
1332         -- no FileOptions here: windres doesn't like seeing
1333         -- backslashes, apparently
1334
1335   return [rc_obj_filename]
1336 #endif
1337
1338
1339 linkDynLib :: DynFlags -> [String] -> [PackageId] -> IO ()
1340 linkDynLib dflags o_files dep_packages = do
1341     let verb = getVerbFlag dflags
1342     let static = opt_Static
1343     let no_hs_main = dopt Opt_NoHsMain dflags
1344     let o_file = outputFile dflags
1345
1346     pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
1347     let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
1348
1349     let lib_paths = libraryPaths dflags
1350     let lib_path_opts = map ("-L"++) lib_paths
1351
1352     pkg_link_opts <- getPackageLinkOpts dflags dep_packages
1353
1354         -- probably _stub.o files
1355     extra_ld_inputs <- readIORef v_Ld_inputs
1356
1357     let (md_c_flags, _) = machdepCCOpts dflags
1358     let extra_ld_opts = getOpts dflags opt_l
1359 #if defined(mingw32_HOST_OS)
1360     -----------------------------------------------------------------------------
1361     -- Making a DLL
1362     -----------------------------------------------------------------------------
1363     let output_fn = case o_file of { Just s -> s; Nothing -> "HSdll.dll"; }
1364
1365     SysTools.runLink dflags
1366          ([ SysTools.Option verb
1367           , SysTools.Option "-o"
1368           , SysTools.FileOption "" output_fn
1369           , SysTools.Option "-shared"
1370           , SysTools.Option "-Wl,--export-all-symbols"
1371           , SysTools.FileOption "-Wl,--out-implib=" (output_fn ++ ".a")
1372           ]
1373          ++ map (SysTools.FileOption "") o_files
1374          ++ map SysTools.Option (
1375             md_c_flags
1376          ++ extra_ld_inputs
1377          ++ lib_path_opts
1378          ++ extra_ld_opts
1379          ++ pkg_lib_path_opts
1380          ++ pkg_link_opts
1381         ))
1382 #elif defined(darwin_TARGET_OS)
1383     -----------------------------------------------------------------------------
1384     -- Making a darwin dylib
1385     -----------------------------------------------------------------------------
1386     -- About the options used for Darwin:
1387     -- -dynamiclib
1388     --   Apple's way of saying -shared
1389     -- -undefined dynamic_lookup:
1390     --   Without these options, we'd have to specify the correct dependencies
1391     --   for each of the dylibs. Note that we could (and should) do without this
1392     --   for all libraries except the RTS; all we need to do is to pass the
1393     --   correct HSfoo_dyn.dylib files to the link command.
1394     --   This feature requires Mac OS X 10.3 or later; there is a similar feature,
1395     --   -flat_namespace -undefined suppress, which works on earlier versions,
1396     --   but it has other disadvantages.
1397     -- -single_module
1398     --   Build the dynamic library as a single "module", i.e. no dynamic binding
1399     --   nonsense when referring to symbols from within the library. The NCG
1400     --   assumes that this option is specified (on i386, at least).
1401     -- -Wl,-macosx_version_min -Wl,10.3
1402     --   Tell the linker its safe to assume that the library will run on 10.3 or
1403     --   later, so that it will not complain about the use of the option
1404     --   -undefined dynamic_lookup above.
1405     -- -install_name
1406     --   Causes the dynamic linker to ignore the DYLD_LIBRARY_PATH when loading
1407     --   this lib and instead look for it at its absolute path.
1408     --   When installing the .dylibs (see target.mk), we'll change that path to
1409     --   point to the place they are installed. Therefore, we won't have to set
1410     --   up DYLD_LIBRARY_PATH specifically for ghc.
1411     -----------------------------------------------------------------------------
1412
1413     let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1414
1415     pwd <- getCurrentDirectory
1416     SysTools.runLink dflags
1417          ([ SysTools.Option verb
1418           , SysTools.Option "-dynamiclib"
1419           , SysTools.Option "-o"
1420           , SysTools.FileOption "" output_fn
1421           ]
1422          ++ map SysTools.Option (
1423             md_c_flags
1424          ++ o_files
1425          ++ [ "-undefined", "dynamic_lookup", "-single_module", "-Wl,-macosx_version_min","-Wl,10.3", "-install_name " ++ (pwd `joinFileName` output_fn) ]
1426          ++ extra_ld_inputs
1427          ++ lib_path_opts
1428          ++ extra_ld_opts
1429          ++ pkg_lib_path_opts
1430          ++ pkg_link_opts
1431         ))
1432 #else
1433     -----------------------------------------------------------------------------
1434     -- Making a DSO
1435     -----------------------------------------------------------------------------
1436
1437     let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1438
1439     SysTools.runLink dflags
1440          ([ SysTools.Option verb
1441           , SysTools.Option "-o"
1442           , SysTools.FileOption "" output_fn
1443           ]
1444          ++ map SysTools.Option (
1445             md_c_flags
1446          ++ o_files
1447          ++ [ "-shared", "-Wl,-Bsymbolic" ] -- we need symbolic linking to resolve non-PIC intra-package-relocations
1448          ++ extra_ld_inputs
1449          ++ lib_path_opts
1450          ++ extra_ld_opts
1451          ++ pkg_lib_path_opts
1452          ++ pkg_link_opts
1453         ))
1454 #endif
1455 -- -----------------------------------------------------------------------------
1456 -- Running CPP
1457
1458 doCpp :: DynFlags -> Bool -> Bool -> FilePath -> FilePath -> IO ()
1459 doCpp dflags raw include_cc_opts input_fn output_fn = do
1460     let hscpp_opts = getOpts dflags opt_P
1461     let cmdline_include_paths = includePaths dflags
1462
1463     pkg_include_dirs <- getPackageIncludePath dflags []
1464     let include_paths = foldr (\ x xs -> "-I" : x : xs) []
1465                           (cmdline_include_paths ++ pkg_include_dirs)
1466
1467     let verb = getVerbFlag dflags
1468
1469     let cc_opts
1470           | not include_cc_opts = []
1471           | otherwise           = (optc ++ md_c_flags)
1472                 where 
1473                       optc = getOpts dflags opt_c
1474                       (md_c_flags, _) = machdepCCOpts dflags
1475
1476     let cpp_prog args | raw       = SysTools.runCpp dflags args
1477                       | otherwise = SysTools.runCc dflags (SysTools.Option "-E" : args)
1478
1479     let target_defs = 
1480           [ "-D" ++ HOST_OS     ++ "_BUILD_OS=1",
1481             "-D" ++ HOST_ARCH   ++ "_BUILD_ARCH=1",
1482             "-D" ++ TARGET_OS   ++ "_HOST_OS=1",
1483             "-D" ++ TARGET_ARCH ++ "_HOST_ARCH=1" ]
1484         -- remember, in code we *compile*, the HOST is the same our TARGET,
1485         -- and BUILD is the same as our HOST.
1486
1487     cpp_prog       ([SysTools.Option verb]
1488                     ++ map SysTools.Option include_paths
1489                     ++ map SysTools.Option hsSourceCppOpts
1490                     ++ map SysTools.Option hscpp_opts
1491                     ++ map SysTools.Option cc_opts
1492                     ++ map SysTools.Option target_defs
1493                     ++ [ SysTools.Option     "-x"
1494                        , SysTools.Option     "c"
1495                        , SysTools.Option     input_fn
1496         -- We hackily use Option instead of FileOption here, so that the file
1497         -- name is not back-slashed on Windows.  cpp is capable of
1498         -- dealing with / in filenames, so it works fine.  Furthermore
1499         -- if we put in backslashes, cpp outputs #line directives
1500         -- with *double* backslashes.   And that in turn means that
1501         -- our error messages get double backslashes in them.
1502         -- In due course we should arrange that the lexer deals
1503         -- with these \\ escapes properly.
1504                        , SysTools.Option     "-o"
1505                        , SysTools.FileOption "" output_fn
1506                        ])
1507
1508 cHaskell1Version = "5" -- i.e., Haskell 98
1509
1510 -- Default CPP defines in Haskell source
1511 hsSourceCppOpts =
1512         [ "-D__HASKELL1__="++cHaskell1Version
1513         , "-D__GLASGOW_HASKELL__="++cProjectVersionInt                          
1514         , "-D__HASKELL98__"
1515         , "-D__CONCURRENT_HASKELL__"
1516         ]
1517
1518
1519 -- -----------------------------------------------------------------------------
1520 -- Misc.
1521
1522 hscNextPhase :: DynFlags -> HscSource -> HscTarget -> Phase
1523 hscNextPhase dflags HsBootFile hsc_lang  =  StopLn
1524 hscNextPhase dflags other hsc_lang = 
1525   case hsc_lang of
1526         HscC -> HCc
1527         HscAsm | dopt Opt_SplitObjs dflags -> SplitMangle
1528                | otherwise -> As
1529         HscNothing     -> StopLn
1530         HscInterpreted -> StopLn
1531         _other         -> StopLn
1532
1533
1534 hscMaybeAdjustTarget :: DynFlags -> Phase -> HscSource -> HscTarget -> HscTarget
1535 hscMaybeAdjustTarget dflags stop other current_hsc_lang 
1536   = hsc_lang 
1537   where
1538         keep_hc = dopt Opt_KeepHcFiles dflags
1539         hsc_lang
1540                 -- don't change the lang if we're interpreting
1541                  | current_hsc_lang == HscInterpreted = current_hsc_lang
1542
1543                 -- force -fvia-C if we are being asked for a .hc file
1544                  | HCc <- stop = HscC
1545                  | keep_hc     = HscC
1546                 -- otherwise, stick to the plan
1547                  | otherwise = current_hsc_lang
1548
1549 GLOBAL_VAR(v_Split_info, ("",0), (String,Int))
1550         -- The split prefix and number of files