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