Remove -fhardwire-lib-paths in favour of -dynload sysdep
[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, 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
586        output_fn <- get_output_fn dflags (Cpp sf) maybe_loc
587
588        let unlit_flags = getOpts dflags opt_L
589            flags = map SysTools.Option unlit_flags ++
590                    [ -- The -h option passes the file name for unlit to
591                      -- put in a #line directive
592                      SysTools.Option     "-h"
593                      -- cpp interprets \b etc as escape sequences,
594                      -- so we use / for filenames in pragmas
595                    , SysTools.Option $ reslash Forwards $ normalise input_fn
596                    , SysTools.FileOption "" input_fn
597                    , SysTools.FileOption "" output_fn
598                    ]
599
600        SysTools.runUnlit dflags flags
601
602        return (Cpp sf, dflags, maybe_loc, output_fn)
603
604 -------------------------------------------------------------------------------
605 -- Cpp phase : (a) gets OPTIONS out of file
606 --             (b) runs cpp if necessary
607
608 runPhase (Cpp sf) _stop dflags0 basename suff input_fn get_output_fn maybe_loc
609   = do src_opts <- getOptionsFromFile input_fn
610        (dflags,unhandled_flags) <- parseDynamicFlags dflags0 (map unLoc src_opts)
611        checkProcessArgsResult unhandled_flags (basename <.> suff)
612
613        if not (dopt Opt_Cpp dflags) then
614            -- no need to preprocess CPP, just pass input file along
615            -- to the next phase of the pipeline.
616           return (HsPp sf, dflags, maybe_loc, input_fn)
617         else do
618             output_fn <- get_output_fn dflags (HsPp sf) maybe_loc
619             doCpp dflags True{-raw-} False{-no CC opts-} input_fn output_fn
620             return (HsPp sf, dflags, maybe_loc, output_fn)
621
622 -------------------------------------------------------------------------------
623 -- HsPp phase 
624
625 runPhase (HsPp sf) _stop dflags basename suff input_fn get_output_fn maybe_loc
626   = do if not (dopt Opt_Pp dflags) then
627            -- no need to preprocess, just pass input file along
628            -- to the next phase of the pipeline.
629           return (Hsc sf, dflags, maybe_loc, input_fn)
630         else do
631             let hspp_opts = getOpts dflags opt_F
632             let orig_fn = basename <.> suff
633             output_fn <- get_output_fn dflags (Hsc sf) maybe_loc
634             SysTools.runPp dflags
635                            ( [ SysTools.Option     orig_fn
636                              , SysTools.Option     input_fn
637                              , SysTools.FileOption "" output_fn
638                              ] ++
639                              map SysTools.Option hspp_opts
640                            )
641             return (Hsc sf, dflags, maybe_loc, output_fn)
642
643 -----------------------------------------------------------------------------
644 -- Hsc phase
645
646 -- Compilation of a single module, in "legacy" mode (_not_ under
647 -- the direction of the compilation manager).
648 runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _maybe_loc 
649  = do   -- normal Hsc mode, not mkdependHS
650
651   -- we add the current directory (i.e. the directory in which
652   -- the .hs files resides) to the include path, since this is
653   -- what gcc does, and it's probably what you want.
654         let current_dir = case takeDirectory basename of
655                       "" -> "." -- XXX Hack
656                       d -> d
657         
658             paths = includePaths dflags0
659             dflags = dflags0 { includePaths = current_dir : paths }
660         
661   -- gather the imports and module name
662         (hspp_buf,mod_name,imps,src_imps) <- 
663             case src_flavour of
664                 ExtCoreFile -> do {  -- no explicit imports in ExtCore input.
665                                   ; m <- getCoreModuleName input_fn
666                                   ; return (Nothing, mkModuleName m, [], []) }
667
668                 _           -> do { buf <- hGetStringBuffer input_fn
669                             ; (src_imps,imps,L _ mod_name) <- getImports dflags buf input_fn (basename <.> suff)
670                             ; return (Just buf, mod_name, imps, src_imps) }
671
672   -- Build a ModLocation to pass to hscMain.
673   -- The source filename is rather irrelevant by now, but it's used
674   -- by hscMain for messages.  hscMain also needs 
675   -- the .hi and .o filenames, and this is as good a way
676   -- as any to generate them, and better than most. (e.g. takes 
677   -- into accout the -osuf flags)
678         location1 <- mkHomeModLocation2 dflags mod_name basename suff
679
680   -- Boot-ify it if necessary
681         let location2 | isHsBoot src_flavour = addBootSuffixLocn location1
682                       | otherwise            = location1 
683                                         
684
685   -- Take -ohi into account if present
686   -- This can't be done in mkHomeModuleLocation because
687   -- it only applies to the module being compiles
688         let ohi = outputHi dflags
689             location3 | Just fn <- ohi = location2{ ml_hi_file = fn }
690                       | otherwise      = location2
691
692   -- Take -o into account if present
693   -- Very like -ohi, but we must *only* do this if we aren't linking
694   -- (If we're linking then the -o applies to the linked thing, not to
695   -- the object file for one module.)
696   -- Note the nasty duplication with the same computation in compileFile above
697         let expl_o_file = outputFile dflags
698             location4 | Just ofile <- expl_o_file
699                       , isNoLink (ghcLink dflags)
700                       = location3 { ml_obj_file = ofile }
701                       | otherwise = location3
702
703             o_file = ml_obj_file location4      -- The real object file
704
705
706   -- Figure out if the source has changed, for recompilation avoidance.
707   --
708   -- Setting source_unchanged to True means that M.o seems
709   -- to be up to date wrt M.hs; so no need to recompile unless imports have
710   -- changed (which the compiler itself figures out).
711   -- Setting source_unchanged to False tells the compiler that M.o is out of
712   -- date wrt M.hs (or M.o doesn't exist) so we must recompile regardless.
713         src_timestamp <- getModificationTime (basename <.> suff)
714
715         let force_recomp = dopt Opt_ForceRecomp dflags
716         source_unchanged <- 
717           if force_recomp || not (isStopLn stop)
718                 -- Set source_unchanged to False unconditionally if
719                 --      (a) recompilation checker is off, or
720                 --      (b) we aren't going all the way to .o file (e.g. ghc -S)
721              then return False  
722                 -- Otherwise look at file modification dates
723              else do o_file_exists <- doesFileExist o_file
724                      if not o_file_exists
725                         then return False       -- Need to recompile
726                         else do t2 <- getModificationTime o_file
727                                 if t2 > src_timestamp
728                                   then return True
729                                   else return False
730
731   -- get the DynFlags
732         let hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
733         let next_phase = hscNextPhase dflags src_flavour hsc_lang
734         output_fn  <- get_output_fn dflags next_phase (Just location4)
735
736         let dflags' = dflags { hscTarget = hsc_lang,
737                                hscOutName = output_fn,
738                                extCoreName = basename ++ ".hcr" }
739
740         hsc_env <- newHscEnv dflags'
741
742   -- Tell the finder cache about this module
743         mod <- addHomeModuleToFinder hsc_env mod_name location4
744
745   -- Make the ModSummary to hand to hscMain
746         let
747             mod_summary = ModSummary {  ms_mod       = mod, 
748                                         ms_hsc_src   = src_flavour,
749                                         ms_hspp_file = input_fn,
750                                         ms_hspp_opts = dflags,
751                                         ms_hspp_buf  = hspp_buf,
752                                         ms_location  = location4,
753                                         ms_hs_date   = src_timestamp,
754                                         ms_obj_date  = Nothing,
755                                         ms_imps      = imps,
756                                         ms_srcimps   = src_imps }
757
758   -- run the compiler!
759         mbResult <- hscCompileOneShot hsc_env
760                           mod_summary source_unchanged 
761                           Nothing       -- No iface
762                           Nothing       -- No "module i of n" progress info
763
764         case mbResult of
765           Nothing -> throwDyn (PhaseFailed "hsc" (ExitFailure 1))
766           Just HscNoRecomp
767               -> do SysTools.touch dflags' "Touching object file" o_file
768                     -- The .o file must have a later modification date
769                     -- than the source file (else we wouldn't be in HscNoRecomp)
770                     -- but we touch it anyway, to keep 'make' happy (we think).
771                     return (StopLn, dflags', Just location4, o_file)
772           Just (HscRecomp hasStub)
773               -> do when hasStub $
774                          do stub_o <- compileStub dflags' mod location4
775                             consIORef v_Ld_inputs stub_o
776                     -- In the case of hs-boot files, generate a dummy .o-boot 
777                     -- stamp file for the benefit of Make
778                     when (isHsBoot src_flavour) $
779                       SysTools.touch dflags' "Touching object file" o_file
780                     return (next_phase, dflags', Just location4, output_fn)
781
782 -----------------------------------------------------------------------------
783 -- Cmm phase
784
785 runPhase CmmCpp _stop dflags _basename _suff input_fn get_output_fn maybe_loc
786   = do
787        output_fn <- get_output_fn dflags Cmm maybe_loc
788        doCpp dflags False{-not raw-} True{-include CC opts-} input_fn output_fn 
789        return (Cmm, dflags, maybe_loc, output_fn)
790
791 runPhase Cmm stop dflags basename _ input_fn get_output_fn maybe_loc
792   = do
793         let hsc_lang = hscMaybeAdjustTarget dflags stop HsSrcFile (hscTarget dflags)
794         let next_phase = hscNextPhase dflags HsSrcFile hsc_lang
795         output_fn <- get_output_fn dflags next_phase maybe_loc
796
797         let dflags' = dflags { hscTarget = hsc_lang,
798                                hscOutName = output_fn,
799                                extCoreName = basename ++ ".hcr" }
800
801         ok <- hscCmmFile dflags' input_fn
802
803         when (not ok) $ throwDyn (PhaseFailed "cmm" (ExitFailure 1))
804
805         return (next_phase, dflags, maybe_loc, output_fn)
806
807 -----------------------------------------------------------------------------
808 -- Cc phase
809
810 -- we don't support preprocessing .c files (with -E) now.  Doing so introduces
811 -- way too many hacks, and I can't say I've ever used it anyway.
812
813 runPhase cc_phase _stop dflags _basename _suff input_fn get_output_fn maybe_loc
814    | cc_phase `eqPhase` Cc || cc_phase `eqPhase` Ccpp || cc_phase `eqPhase` HCc
815    = do let cc_opts = getOpts dflags opt_c
816             hcc = cc_phase `eqPhase` HCc
817
818         let cmdline_include_paths = includePaths dflags
819
820         -- HC files have the dependent packages stamped into them
821         pkgs <- if hcc then getHCFilePackages input_fn else return []
822
823         -- add package include paths even if we're just compiling .c
824         -- files; this is the Value Add(TM) that using ghc instead of
825         -- gcc gives you :)
826         pkg_include_dirs <- getPackageIncludePath dflags pkgs
827         let include_paths = foldr (\ x xs -> "-I" : x : xs) []
828                               (cmdline_include_paths ++ pkg_include_dirs)
829
830         let (md_c_flags, md_regd_c_flags) = machdepCCOpts dflags
831         gcc_extra_viac_flags <- getExtraViaCOpts dflags
832         let pic_c_flags = picCCOpts dflags
833
834         let verb = getVerbFlag dflags
835
836         pkg_extra_cc_opts <- getPackageExtraCcOpts dflags pkgs
837
838         let split_objs = dopt Opt_SplitObjs dflags
839             split_opt | hcc && split_objs = [ "-DUSE_SPLIT_MARKERS" ]
840                       | otherwise         = [ ]
841
842         let cc_opt | optLevel dflags >= 2 = "-O2"
843                    | otherwise            = "-O"
844
845         -- Decide next phase
846         
847         let mangle = dopt Opt_DoAsmMangling dflags
848             next_phase
849                 | hcc && mangle     = Mangle
850                 | otherwise         = As
851         output_fn <- get_output_fn dflags next_phase maybe_loc
852
853         let
854           more_hcc_opts =
855 #if i386_TARGET_ARCH
856                 -- on x86 the floating point regs have greater precision
857                 -- than a double, which leads to unpredictable results.
858                 -- By default, we turn this off with -ffloat-store unless
859                 -- the user specified -fexcess-precision.
860                 (if dopt Opt_ExcessPrecision dflags 
861                         then [] 
862                         else [ "-ffloat-store" ]) ++
863 #endif
864                 -- gcc's -fstrict-aliasing allows two accesses to memory
865                 -- to be considered non-aliasing if they have different types.
866                 -- This interacts badly with the C code we generate, which is
867                 -- very weakly typed, being derived from C--.
868                 ["-fno-strict-aliasing"]
869
870
871
872         SysTools.runCc dflags (
873                 -- force the C compiler to interpret this file as C when
874                 -- compiling .hc files, by adding the -x c option.
875                 -- Also useful for plain .c files, just in case GHC saw a 
876                 -- -x c option.
877                         [ SysTools.Option "-x", if cc_phase `eqPhase` Ccpp
878                                                 then SysTools.Option "c++" else SysTools.Option "c"] ++
879                         [ SysTools.FileOption "" input_fn
880                         , SysTools.Option "-o"
881                         , SysTools.FileOption "" output_fn
882                         ]
883                        ++ map SysTools.Option (
884                           md_c_flags
885                        ++ pic_c_flags
886 #ifdef sparc_TARGET_ARCH
887         -- We only support SparcV9 and better because V8 lacks an atomic CAS
888         -- instruction. Note that the user can still override this
889         -- (e.g., -mcpu=ultrasparc) as GCC picks the "best" -mcpu flag
890         -- regardless of the ordering.
891         --
892         -- This is a temporary hack.
893                        ++ ["-mcpu=v9"]
894 #endif
895                        ++ (if hcc && mangle
896                              then md_regd_c_flags
897                              else [])
898                        ++ (if hcc
899                              then if mangle 
900                                      then gcc_extra_viac_flags
901                                      else filter (=="-fwrapv")
902                                                 gcc_extra_viac_flags
903                                 -- still want -fwrapv even for unreg'd
904                              else [])
905                        ++ (if hcc 
906                              then more_hcc_opts
907                              else [])
908                        ++ [ verb, "-S", "-Wimplicit", cc_opt ]
909                        ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
910                        ++ cc_opts
911                        ++ split_opt
912                        ++ include_paths
913                        ++ pkg_extra_cc_opts
914                        ))
915
916         return (next_phase, dflags, maybe_loc, output_fn)
917
918         -- ToDo: postprocess the output from gcc
919
920 -----------------------------------------------------------------------------
921 -- Mangle phase
922
923 runPhase Mangle _stop dflags _basename _suff input_fn get_output_fn maybe_loc
924    = do let mangler_opts = getOpts dflags opt_m
925
926 #if i386_TARGET_ARCH
927         machdep_opts <- return [ show (stolen_x86_regs dflags) ]
928 #else
929         machdep_opts <- return []
930 #endif
931
932         let split = dopt Opt_SplitObjs dflags
933             next_phase
934                 | split = SplitMangle
935                 | otherwise = As
936         output_fn <- get_output_fn dflags next_phase maybe_loc
937
938         SysTools.runMangle dflags (map SysTools.Option mangler_opts
939                           ++ [ SysTools.FileOption "" input_fn
940                              , SysTools.FileOption "" output_fn
941                              ]
942                           ++ map SysTools.Option machdep_opts)
943
944         return (next_phase, dflags, maybe_loc, output_fn)
945
946 -----------------------------------------------------------------------------
947 -- Splitting phase
948
949 runPhase SplitMangle _stop dflags _basename _suff input_fn _get_output_fn maybe_loc
950   = do  -- tmp_pfx is the prefix used for the split .s files
951         -- We also use it as the file to contain the no. of split .s files (sigh)
952         split_s_prefix <- SysTools.newTempName dflags "split"
953         let n_files_fn = split_s_prefix
954
955         SysTools.runSplit dflags
956                           [ SysTools.FileOption "" input_fn
957                           , SysTools.FileOption "" split_s_prefix
958                           , SysTools.FileOption "" n_files_fn
959                           ]
960
961         -- Save the number of split files for future references
962         s <- readFile n_files_fn
963         let n_files = read s :: Int
964         writeIORef v_Split_info (split_s_prefix, n_files)
965
966         -- Remember to delete all these files
967         addFilesToClean [ split_s_prefix ++ "__" ++ show n ++ ".s"
968                         | n <- [1..n_files]]
969
970         return (SplitAs, dflags, maybe_loc, "**splitmangle**")
971           -- we don't use the filename
972
973 -----------------------------------------------------------------------------
974 -- As phase
975
976 runPhase As _stop dflags _basename _suff input_fn get_output_fn maybe_loc
977   = do  let as_opts =  getOpts dflags opt_a
978         let cmdline_include_paths = includePaths dflags
979
980         output_fn <- get_output_fn dflags StopLn maybe_loc
981
982         -- we create directories for the object file, because it
983         -- might be a hierarchical module.
984         createDirectoryHierarchy (takeDirectory output_fn)
985
986         SysTools.runAs dflags   
987                        (map SysTools.Option as_opts
988                        ++ [ SysTools.Option ("-I" ++ p) | p <- cmdline_include_paths ]
989 #ifdef sparc_TARGET_ARCH
990         -- We only support SparcV9 and better because V8 lacks an atomic CAS
991         -- instruction so we have to make sure that the assembler accepts the
992         -- instruction set. Note that the user can still override this
993         -- (e.g., -mcpu=ultrasparc). GCC picks the "best" -mcpu flag
994         -- regardless of the ordering.
995         --
996         -- This is a temporary hack.
997                        ++ [ SysTools.Option "-mcpu=v9" ]
998 #endif
999                        ++ [ SysTools.Option "-c"
1000                           , SysTools.FileOption "" input_fn
1001                           , SysTools.Option "-o"
1002                           , SysTools.FileOption "" output_fn
1003                           ])
1004
1005         return (StopLn, dflags, maybe_loc, output_fn)
1006
1007
1008 runPhase SplitAs _stop dflags _basename _suff _input_fn get_output_fn maybe_loc
1009   = do
1010         output_fn <- get_output_fn dflags StopLn maybe_loc
1011
1012         let base_o = dropExtension output_fn
1013             split_odir  = base_o ++ "_split"
1014             osuf = objectSuf dflags
1015
1016         createDirectoryHierarchy split_odir
1017
1018         -- remove M_split/ *.o, because we're going to archive M_split/ *.o
1019         -- later and we don't want to pick up any old objects.
1020         fs <- getDirectoryContents split_odir
1021         mapM_ removeFile $ map (split_odir </>) $ filter (osuf `isSuffixOf`) fs
1022
1023         let as_opts = getOpts dflags opt_a
1024
1025         (split_s_prefix, n) <- readIORef v_Split_info
1026
1027         let split_s   n = split_s_prefix ++ "__" ++ show n <.> "s"
1028             split_obj n = split_odir </>
1029                           takeFileName base_o ++ "__" ++ show n <.> osuf
1030
1031         let assemble_file n
1032               = SysTools.runAs dflags
1033                          (map SysTools.Option as_opts ++
1034                           [ SysTools.Option "-c"
1035                           , SysTools.Option "-o"
1036                           , SysTools.FileOption "" (split_obj n)
1037                           , SysTools.FileOption "" (split_s n)
1038                           ])
1039
1040         mapM_ assemble_file [1..n]
1041
1042         -- and join the split objects into a single object file:
1043         let ld_r args = SysTools.runLink dflags ([
1044                             SysTools.Option "-nostdlib",
1045                             SysTools.Option "-nodefaultlibs",
1046                             SysTools.Option "-Wl,-r",
1047                             SysTools.Option ld_x_flag,
1048                             SysTools.Option "-o",
1049                             SysTools.FileOption "" output_fn ] ++ args)
1050             ld_x_flag | null cLD_X = ""
1051                       | otherwise  = "-Wl,-x"
1052
1053         if cLdIsGNULd == "YES"
1054             then do
1055                   let script = split_odir </> "ld.script"
1056                   writeFile script $
1057                       "INPUT(" ++ unwords (map split_obj [1..n]) ++ ")"
1058                   ld_r [SysTools.FileOption "" script]
1059             else do
1060                   ld_r (map (SysTools.FileOption "" . split_obj) [1..n])
1061
1062         return (StopLn, dflags, maybe_loc, output_fn)
1063
1064 -- warning suppression
1065 runPhase other _stop _dflags _basename _suff _input_fn _get_output_fn _maybe_loc =
1066    panic ("runPhase: don't know how to run phase " ++ show other)
1067 -----------------------------------------------------------------------------
1068 -- MoveBinary sort-of-phase
1069 -- After having produced a binary, move it somewhere else and generate a
1070 -- wrapper script calling the binary. Currently, we need this only in 
1071 -- a parallel way (i.e. in GUM), because PVM expects the binary in a
1072 -- central directory.
1073 -- This is called from linkBinary below, after linking. I haven't made it
1074 -- a separate phase to minimise interfering with other modules, and
1075 -- we don't need the generality of a phase (MoveBinary is always
1076 -- done after linking and makes only sense in a parallel setup)   -- HWL
1077
1078 runPhase_MoveBinary :: DynFlags -> FilePath -> IO Bool 
1079 runPhase_MoveBinary dflags input_fn
1080   = do  
1081         let sysMan = pgm_sysman dflags
1082         pvm_root <- getEnv "PVM_ROOT"
1083         pvm_arch <- getEnv "PVM_ARCH"
1084         let 
1085            pvm_executable_base = "=" ++ input_fn
1086            pvm_executable = pvm_root ++ "/bin/" ++ pvm_arch ++ "/" ++ pvm_executable_base
1087         -- nuke old binary; maybe use configur'ed names for cp and rm?
1088         Panic.try (removeFile pvm_executable)
1089         -- move the newly created binary into PVM land
1090         copy dflags "copying PVM executable" input_fn pvm_executable
1091         -- generate a wrapper script for running a parallel prg under PVM
1092         writeFile input_fn (mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan)
1093         return True
1094
1095 -- generates a Perl skript starting a parallel prg under PVM
1096 mk_pvm_wrapper_script :: String -> String -> String -> String
1097 mk_pvm_wrapper_script pvm_executable pvm_executable_base sysMan = unlines $
1098  [
1099   "eval 'exec perl -S $0 ${1+\"$@\"}'", 
1100   "  if $running_under_some_shell;",
1101   "# =!=!=!=!=!=!=!=!=!=!=!",
1102   "# This script is automatically generated: DO NOT EDIT!!!",
1103   "# Generated by Glasgow Haskell Compiler",
1104   "# ngoqvam choHbogh vaj' vIHoHnISbej !!!!",
1105   "#",
1106   "$pvm_executable      = '" ++ pvm_executable ++ "';",
1107   "$pvm_executable_base = '" ++ pvm_executable_base ++ "';",
1108   "$SysMan = '" ++ sysMan ++ "';",
1109   "",
1110   {- ToDo: add the magical shortcuts again iff we actually use them -- HWL
1111   "# first, some magical shortcuts to run "commands" on the binary",
1112   "# (which is hidden)",
1113   "if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {",
1114   "    local($cmd) = $1;",
1115   "    system("$cmd $pvm_executable");",
1116   "    exit(0); # all done",
1117   "}", -}
1118   "",
1119   "# Now, run the real binary; process the args first",
1120   "$ENV{'PE'} = $pvm_executable_base;", --  ++ pvm_executable_base,
1121   "$debug = '';",
1122   "$nprocessors = 0; # the default: as many PEs as machines in PVM config",
1123   "@nonPVM_args = ();",
1124   "$in_RTS_args = 0;",
1125   "",
1126   "args: while ($a = shift(@ARGV)) {",
1127   "    if ( $a eq '+RTS' ) {",
1128   "        $in_RTS_args = 1;",
1129   "    } elsif ( $a eq '-RTS' ) {",
1130   "        $in_RTS_args = 0;",
1131   "    }",
1132   "    if ( $a eq '-d' && $in_RTS_args ) {",
1133   "        $debug = '-';",
1134   "    } elsif ( $a =~ /^-qN(\\d+)/ && $in_RTS_args ) {",
1135   "        $nprocessors = $1;",
1136   "    } elsif ( $a =~ /^-qp(\\d+)/ && $in_RTS_args ) {",
1137   "        $nprocessors = $1;",
1138   "    } else {",
1139   "        push(@nonPVM_args, $a);",
1140   "    }",
1141   "}",
1142   "",
1143   "local($return_val) = 0;",
1144   "# Start the parallel execution by calling SysMan",
1145   "system(\"$SysMan $debug $pvm_executable $nprocessors @nonPVM_args\");",
1146   "$return_val = $?;",
1147   "# ToDo: fix race condition moving files and flushing them!!",
1148   "system(\"cp $ENV{'HOME'}/$pvm_executable_base.???.gr .\") if -f \"$ENV{'HOME'}/$pvm_executable_base.002.gr\";",
1149   "exit($return_val);"
1150  ]
1151
1152 -----------------------------------------------------------------------------
1153 -- Complain about non-dynamic flags in OPTIONS pragmas
1154
1155 checkProcessArgsResult :: [String] -> FilePath -> IO ()
1156 checkProcessArgsResult flags filename
1157   = do when (notNull flags) (throwDyn (ProgramError (
1158           showSDoc (hang (text filename <> char ':')
1159                       4 (text "unknown flags in  {-# OPTIONS #-} pragma:" <+>
1160                           hsep (map text flags)))
1161         )))
1162
1163 -----------------------------------------------------------------------------
1164 -- Look for the /* GHC_PACKAGES ... */ comment at the top of a .hc file
1165
1166 getHCFilePackages :: FilePath -> IO [PackageId]
1167 getHCFilePackages filename =
1168   Exception.bracket (openFile filename ReadMode) hClose $ \h -> do
1169     l <- hGetLine h
1170     case l of
1171       '/':'*':' ':'G':'H':'C':'_':'P':'A':'C':'K':'A':'G':'E':'S':rest ->
1172           return (map stringToPackageId (words rest))
1173       _other ->
1174           return []
1175
1176 -----------------------------------------------------------------------------
1177 -- Static linking, of .o files
1178
1179 -- The list of packages passed to link is the list of packages on
1180 -- which this program depends, as discovered by the compilation
1181 -- manager.  It is combined with the list of packages that the user
1182 -- specifies on the command line with -package flags.  
1183 --
1184 -- In one-shot linking mode, we can't discover the package
1185 -- dependencies (because we haven't actually done any compilation or
1186 -- read any interface files), so the user must explicitly specify all
1187 -- the packages.
1188
1189 linkBinary :: DynFlags -> [FilePath] -> [PackageId] -> IO ()
1190 linkBinary dflags o_files dep_packages = do
1191     let verb = getVerbFlag dflags
1192         output_fn = exeFileName dflags
1193
1194     -- get the full list of packages to link with, by combining the
1195     -- explicit packages with the auto packages and all of their
1196     -- dependencies, and eliminating duplicates.
1197
1198     pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
1199     let pkg_lib_path_opts = concat (map get_pkg_lib_path_opts pkg_lib_paths)
1200 #ifdef linux_TARGET_OS
1201         get_pkg_lib_path_opts l | (dynLibLoader dflags)==SystemDependent && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
1202                                 | otherwise = ["-L" ++ l]
1203 #else
1204         get_pkg_lib_path_opts l = ["-L" ++ l]
1205 #endif
1206
1207     let lib_paths = libraryPaths dflags
1208     let lib_path_opts = map ("-L"++) lib_paths
1209
1210     pkg_link_opts <- getPackageLinkOpts dflags dep_packages
1211
1212 #ifdef darwin_TARGET_OS
1213     pkg_framework_paths <- getPackageFrameworkPath dflags dep_packages
1214     let pkg_framework_path_opts = map ("-F"++) pkg_framework_paths
1215
1216     let framework_paths = frameworkPaths dflags
1217         framework_path_opts = map ("-F"++) framework_paths
1218
1219     pkg_frameworks <- getPackageFrameworks dflags dep_packages
1220     let pkg_framework_opts = concat [ ["-framework", fw] | fw <- pkg_frameworks ]
1221     
1222     let frameworks = cmdlineFrameworks dflags
1223         framework_opts = concat [ ["-framework", fw] | fw <- reverse frameworks ]
1224          -- reverse because they're added in reverse order from the cmd line
1225 #endif
1226 #ifdef mingw32_TARGET_OS
1227     let dynMain = if not opt_Static then
1228                       (head (libraryDirs (getPackageDetails (pkgState dflags) rtsPackageId))) ++ "/Main.dyn_o"
1229                   else
1230                       ""
1231 #endif
1232         -- probably _stub.o files
1233     extra_ld_inputs <- readIORef v_Ld_inputs
1234
1235         -- opts from -optl-<blah> (including -l<blah> options)
1236     let extra_ld_opts = getOpts dflags opt_l
1237
1238     let ways = wayNames dflags
1239
1240     -- Here are some libs that need to be linked at the *end* of
1241     -- the command line, because they contain symbols that are referred to
1242     -- by the RTS.  We can't therefore use the ordinary way opts for these.
1243     let
1244         debug_opts | WayDebug `elem` ways = [ 
1245 #if defined(HAVE_LIBBFD)
1246                         "-lbfd", "-liberty"
1247 #endif
1248                          ]
1249                    | otherwise            = []
1250
1251     let
1252         thread_opts | WayThreaded `elem` ways = [ 
1253 #if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS)
1254                         "-lpthread"
1255 #endif
1256 #if defined(osf3_TARGET_OS)
1257                         , "-lexc"
1258 #endif
1259                         ]
1260                     | otherwise               = []
1261
1262     rc_objs <- maybeCreateManifest dflags output_fn
1263
1264     let (md_c_flags, _) = machdepCCOpts dflags
1265     SysTools.runLink dflags ( 
1266                        [ SysTools.Option verb
1267                        , SysTools.Option "-o"
1268                        , SysTools.FileOption "" output_fn
1269                        ]
1270                       ++ map SysTools.Option (
1271                          md_c_flags
1272                       ++ o_files
1273 #ifdef mingw32_TARGET_OS
1274                       ++ [dynMain]
1275 #endif
1276                       ++ extra_ld_inputs
1277                       ++ lib_path_opts
1278                       ++ extra_ld_opts
1279                       ++ rc_objs
1280 #ifdef darwin_TARGET_OS
1281                       ++ framework_path_opts
1282                       ++ framework_opts
1283 #endif
1284                       ++ pkg_lib_path_opts
1285                       ++ pkg_link_opts
1286 #ifdef darwin_TARGET_OS
1287                       ++ pkg_framework_path_opts
1288                       ++ pkg_framework_opts
1289 #endif
1290                       ++ debug_opts
1291                       ++ thread_opts
1292                     ))
1293
1294     -- parallel only: move binary to another dir -- HWL
1295     when (WayPar `elem` ways)
1296          (do success <- runPhase_MoveBinary dflags output_fn
1297              if success then return ()
1298                         else throwDyn (InstallationError ("cannot move binary to PVM dir")))
1299
1300
1301 exeFileName :: DynFlags -> FilePath
1302 exeFileName dflags
1303   | Just s <- outputFile dflags =
1304 #if defined(mingw32_HOST_OS)
1305       if null (takeExtension s)
1306         then s <.> "exe"
1307         else s
1308 #else
1309       s
1310 #endif
1311   | otherwise = 
1312 #if defined(mingw32_HOST_OS)
1313         "main.exe"
1314 #else
1315         "a.out"
1316 #endif
1317
1318 maybeCreateManifest
1319    :: DynFlags
1320    -> FilePath                          -- filename of executable
1321    -> IO [FilePath]                     -- extra objects to embed, maybe
1322 #ifndef mingw32_TARGET_OS
1323 maybeCreateManifest _ _ = do
1324   return []
1325 #else
1326 maybeCreateManifest dflags exe_filename = do
1327   if not (dopt Opt_GenManifest dflags) then return [] else do
1328
1329   let manifest_filename = exe_filename <.> "manifest"
1330
1331   writeFile manifest_filename $ 
1332       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"++
1333       "  <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"++
1334       "  <assemblyIdentity version=\"1.0.0.0\"\n"++
1335       "     processorArchitecture=\"X86\"\n"++
1336       "     name=\"" ++ dropExtension exe_filename ++ "\"\n"++
1337       "     type=\"win32\"/>\n\n"++
1338       "  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n"++
1339       "    <security>\n"++
1340       "      <requestedPrivileges>\n"++
1341       "        <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n"++
1342       "        </requestedPrivileges>\n"++
1343       "       </security>\n"++
1344       "  </trustInfo>\n"++
1345       "</assembly>\n"
1346
1347   -- Windows will find the manifest file if it is named foo.exe.manifest.
1348   -- However, for extra robustness, and so that we can move the binary around,
1349   -- we can embed the manifest in the binary itself using windres:
1350   if not (dopt Opt_EmbedManifest dflags) then return [] else do
1351
1352   rc_filename <- newTempName dflags "rc"
1353   rc_obj_filename <- newTempName dflags (objectSuf dflags)
1354
1355   writeFile rc_filename $
1356       "1 24 MOVEABLE PURE " ++ show manifest_filename ++ "\n"
1357         -- magic numbers :-)
1358         -- show is a bit hackish above, but we need to escape the
1359         -- backslashes in the path.
1360
1361   let wr_opts = getOpts dflags opt_windres
1362   runWindres dflags $ map SysTools.Option $
1363         ["--input="++rc_filename, 
1364          "--output="++rc_obj_filename,
1365          "--output-format=coff"] 
1366         ++ wr_opts
1367         -- no FileOptions here: windres doesn't like seeing
1368         -- backslashes, apparently
1369
1370   return [rc_obj_filename]
1371 #endif
1372
1373
1374 linkDynLib :: DynFlags -> [String] -> [PackageId] -> IO ()
1375 linkDynLib dflags o_files dep_packages = do
1376     let verb = getVerbFlag dflags
1377     let o_file = outputFile dflags
1378
1379     pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
1380     let pkg_lib_path_opts = map ("-L"++) pkg_lib_paths
1381
1382     let lib_paths = libraryPaths dflags
1383     let lib_path_opts = map ("-L"++) lib_paths
1384
1385     pkg_link_opts <- getPackageLinkOpts dflags dep_packages
1386
1387         -- probably _stub.o files
1388     extra_ld_inputs <- readIORef v_Ld_inputs
1389
1390     let (md_c_flags, _) = machdepCCOpts dflags
1391     let extra_ld_opts = getOpts dflags opt_l
1392 #if defined(mingw32_HOST_OS)
1393     -----------------------------------------------------------------------------
1394     -- Making a DLL
1395     -----------------------------------------------------------------------------
1396     let output_fn = case o_file of { Just s -> s; Nothing -> "HSdll.dll"; }
1397
1398     SysTools.runLink dflags
1399          ([ SysTools.Option verb
1400           , SysTools.Option "-o"
1401           , SysTools.FileOption "" output_fn
1402           , SysTools.Option "-shared"
1403           , SysTools.FileOption "-Wl,--out-implib=" (output_fn ++ ".a")
1404           ]
1405          ++ map (SysTools.FileOption "") o_files
1406          ++ map SysTools.Option (
1407             md_c_flags
1408          ++ extra_ld_inputs
1409          ++ lib_path_opts
1410          ++ extra_ld_opts
1411          ++ pkg_lib_path_opts
1412          ++ pkg_link_opts
1413         ))
1414 #elif defined(darwin_TARGET_OS)
1415     -----------------------------------------------------------------------------
1416     -- Making a darwin dylib
1417     -----------------------------------------------------------------------------
1418     -- About the options used for Darwin:
1419     -- -dynamiclib
1420     --   Apple's way of saying -shared
1421     -- -undefined dynamic_lookup:
1422     --   Without these options, we'd have to specify the correct dependencies
1423     --   for each of the dylibs. Note that we could (and should) do without this
1424     --   for all libraries except the RTS; all we need to do is to pass the
1425     --   correct HSfoo_dyn.dylib files to the link command.
1426     --   This feature requires Mac OS X 10.3 or later; there is a similar feature,
1427     --   -flat_namespace -undefined suppress, which works on earlier versions,
1428     --   but it has other disadvantages.
1429     -- -single_module
1430     --   Build the dynamic library as a single "module", i.e. no dynamic binding
1431     --   nonsense when referring to symbols from within the library. The NCG
1432     --   assumes that this option is specified (on i386, at least).
1433     -- -Wl,-macosx_version_min -Wl,10.3
1434     --   Tell the linker its safe to assume that the library will run on 10.3 or
1435     --   later, so that it will not complain about the use of the option
1436     --   -undefined dynamic_lookup above.
1437     -- -install_name
1438     --   Causes the dynamic linker to ignore the DYLD_LIBRARY_PATH when loading
1439     --   this lib and instead look for it at its absolute path.
1440     --   When installing the .dylibs (see target.mk), we'll change that path to
1441     --   point to the place they are installed. Therefore, we won't have to set
1442     --   up DYLD_LIBRARY_PATH specifically for ghc.
1443     -----------------------------------------------------------------------------
1444
1445     let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1446
1447     pwd <- getCurrentDirectory
1448     SysTools.runLink dflags
1449          ([ SysTools.Option verb
1450           , SysTools.Option "-dynamiclib"
1451           , SysTools.Option "-o"
1452           , SysTools.FileOption "" output_fn
1453           ]
1454          ++ map SysTools.Option (
1455             md_c_flags
1456          ++ o_files
1457          ++ [ "-undefined", "dynamic_lookup", "-single_module", "-Wl,-macosx_version_min","-Wl,10.3", "-install_name " ++ (pwd </> output_fn) ]
1458          ++ extra_ld_inputs
1459          ++ lib_path_opts
1460          ++ extra_ld_opts
1461          ++ pkg_lib_path_opts
1462          ++ pkg_link_opts
1463         ))
1464 #else
1465     -----------------------------------------------------------------------------
1466     -- Making a DSO
1467     -----------------------------------------------------------------------------
1468
1469     let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
1470
1471     SysTools.runLink dflags
1472          ([ SysTools.Option verb
1473           , SysTools.Option "-o"
1474           , SysTools.FileOption "" output_fn
1475           ]
1476          ++ map SysTools.Option (
1477             md_c_flags
1478          ++ o_files
1479          ++ [ "-shared", "-Wl,-Bsymbolic" ] -- we need symbolic linking to resolve non-PIC intra-package-relocations
1480          ++ extra_ld_inputs
1481          ++ lib_path_opts
1482          ++ extra_ld_opts
1483          ++ pkg_lib_path_opts
1484          ++ pkg_link_opts
1485         ))
1486 #endif
1487 -- -----------------------------------------------------------------------------
1488 -- Running CPP
1489
1490 doCpp :: DynFlags -> Bool -> Bool -> FilePath -> FilePath -> IO ()
1491 doCpp dflags raw include_cc_opts input_fn output_fn = do
1492     let hscpp_opts = getOpts dflags opt_P
1493     let cmdline_include_paths = includePaths dflags
1494
1495     pkg_include_dirs <- getPackageIncludePath dflags []
1496     let include_paths = foldr (\ x xs -> "-I" : x : xs) []
1497                           (cmdline_include_paths ++ pkg_include_dirs)
1498
1499     let verb = getVerbFlag dflags
1500
1501     let cc_opts
1502           | not include_cc_opts = []
1503           | otherwise           = (optc ++ md_c_flags)
1504                 where 
1505                       optc = getOpts dflags opt_c
1506                       (md_c_flags, _) = machdepCCOpts dflags
1507
1508     let cpp_prog args | raw       = SysTools.runCpp dflags args
1509                       | otherwise = SysTools.runCc dflags (SysTools.Option "-E" : args)
1510
1511     let target_defs = 
1512           [ "-D" ++ HOST_OS     ++ "_BUILD_OS=1",
1513             "-D" ++ HOST_ARCH   ++ "_BUILD_ARCH=1",
1514             "-D" ++ TARGET_OS   ++ "_HOST_OS=1",
1515             "-D" ++ TARGET_ARCH ++ "_HOST_ARCH=1" ]
1516         -- remember, in code we *compile*, the HOST is the same our TARGET,
1517         -- and BUILD is the same as our HOST.
1518
1519     cpp_prog       ([SysTools.Option verb]
1520                     ++ map SysTools.Option include_paths
1521                     ++ map SysTools.Option hsSourceCppOpts
1522                     ++ map SysTools.Option hscpp_opts
1523                     ++ map SysTools.Option cc_opts
1524                     ++ map SysTools.Option target_defs
1525                     ++ [ SysTools.Option     "-x"
1526                        , SysTools.Option     "c"
1527                        , SysTools.Option     input_fn
1528         -- We hackily use Option instead of FileOption here, so that the file
1529         -- name is not back-slashed on Windows.  cpp is capable of
1530         -- dealing with / in filenames, so it works fine.  Furthermore
1531         -- if we put in backslashes, cpp outputs #line directives
1532         -- with *double* backslashes.   And that in turn means that
1533         -- our error messages get double backslashes in them.
1534         -- In due course we should arrange that the lexer deals
1535         -- with these \\ escapes properly.
1536                        , SysTools.Option     "-o"
1537                        , SysTools.FileOption "" output_fn
1538                        ])
1539
1540 cHaskell1Version :: String
1541 cHaskell1Version = "5" -- i.e., Haskell 98
1542
1543 hsSourceCppOpts :: [String]
1544 -- Default CPP defines in Haskell source
1545 hsSourceCppOpts =
1546         [ "-D__HASKELL1__="++cHaskell1Version
1547         , "-D__GLASGOW_HASKELL__="++cProjectVersionInt                          
1548         , "-D__HASKELL98__"
1549         , "-D__CONCURRENT_HASKELL__"
1550         ]
1551
1552
1553 -- -----------------------------------------------------------------------------
1554 -- Misc.
1555
1556 hscNextPhase :: DynFlags -> HscSource -> HscTarget -> Phase
1557 hscNextPhase _ HsBootFile _        =  StopLn
1558 hscNextPhase dflags _ hsc_lang = 
1559   case hsc_lang of
1560         HscC -> HCc
1561         HscAsm | dopt Opt_SplitObjs dflags -> SplitMangle
1562                | otherwise -> As
1563         HscNothing     -> StopLn
1564         HscInterpreted -> StopLn
1565         _other         -> StopLn
1566
1567
1568 hscMaybeAdjustTarget :: DynFlags -> Phase -> HscSource -> HscTarget -> HscTarget
1569 hscMaybeAdjustTarget dflags stop _ current_hsc_lang 
1570   = hsc_lang 
1571   where
1572         keep_hc = dopt Opt_KeepHcFiles dflags
1573         hsc_lang
1574                 -- don't change the lang if we're interpreting
1575                  | current_hsc_lang == HscInterpreted = current_hsc_lang
1576
1577                 -- force -fvia-C if we are being asked for a .hc file
1578                  | HCc <- stop = HscC
1579                  | keep_hc     = HscC
1580                 -- otherwise, stick to the plan
1581                  | otherwise = current_hsc_lang
1582
1583 v_Split_info :: IORef (String, Int)
1584 GLOBAL_VAR(v_Split_info, ("",0), (String,Int))
1585         -- The split prefix and number of files