Main.hs 35.8 KB
Newer Older
1
{-# LANGUAGE CPP, NondecreasingIndentation, TupleSections #-}
2
{-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}
3

4
5
6
7
-----------------------------------------------------------------------------
--
-- GHC Driver program
--
8
-- (c) The University of Glasgow 2005
9
10
11
12
13
--
-----------------------------------------------------------------------------

module Main (main) where

14
15
-- The official GHC API
import qualified GHC
dterei's avatar
dterei committed
16
import GHC              ( -- DynFlags(..), HscTarget(..),
17
                          -- GhcMode(..), GhcLink(..),
18
                          Ghc, GhcMonad(..),
dterei's avatar
dterei committed
19
                          LoadHowMuch(..) )
20
import CmdLineParser
21

22
-- Implementations of the various modes (--show-iface, mkdependHS. etc.)
dterei's avatar
dterei committed
23
import LoadIface        ( showIface )
24
import HscMain          ( newHscEnv )
25
import DriverPipeline   ( oneShot, compileFile, mergeRequirement )
dterei's avatar
dterei committed
26
import DriverMkDepend   ( doMkDependHS )
27
#ifdef GHCI
28
import InteractiveUI    ( interactiveUI, ghciWelcomeMsg, defaultGhciSettings )
29
#endif
30

31

32
-- Various other random stuff that we need
Ian Lynagh's avatar
Ian Lynagh committed
33
import Config
Ian Lynagh's avatar
Ian Lynagh committed
34
import Constants
dias@eecs.harvard.edu's avatar
dias@eecs.harvard.edu committed
35
import HscTypes
36
import Packages         ( pprPackages, pprPackagesSimple, pprModuleMap )
37
import DriverPhases
Thomas Schilling's avatar
Thomas Schilling committed
38
import BasicTypes       ( failed )
39
import StaticFlags
Ian Lynagh's avatar
Ian Lynagh committed
40
import DynFlags
41
import ErrUtils
Ian Lynagh's avatar
Ian Lynagh committed
42
import FastString
43
import Outputable
44
import SrcLoc
45
import Util
46
import Panic
47
import MonadUtils       ( liftIO )
48

49
50
51
52
53
54
55
-- Imports for --abi-hash
import LoadIface           ( loadUserInterface )
import Module              ( mkModuleName )
import Finder              ( findImportedModule, cannotFindInterface )
import TcRnMonad           ( initIfaceCheck )
import Binary              ( openBinMem, put_, fingerprintBinMem )

56
-- Standard Haskell libraries
Simon Marlow's avatar
Simon Marlow committed
57
58
59
import System.IO
import System.Environment
import System.Exit
Ian Lynagh's avatar
Ian Lynagh committed
60
import System.FilePath
Simon Marlow's avatar
Simon Marlow committed
61
import Control.Monad
62
import Data.Char
Simon Marlow's avatar
Simon Marlow committed
63
64
import Data.List
import Data.Maybe
65

66
67
68
69
70
71
72
-----------------------------------------------------------------------------
-- ToDo:

-- time commands when run with -v
-- user ways
-- Win32 support: proper signal handling
-- reading the package configuration file is too slow
73
-- -K<size>
74
75

-----------------------------------------------------------------------------
76
-- GHC's command-line interface
77

Ian Lynagh's avatar
Ian Lynagh committed
78
main :: IO ()
79
main = do
Austin Seipp's avatar
Austin Seipp committed
80
   initGCStatistics -- See Note [-Bsymbolic and hooks]
parcs's avatar
parcs committed
81
82
   hSetBuffering stdout LineBuffering
   hSetBuffering stderr LineBuffering
83
84
85
86
87
88
89
90
91
92
93
94

   -- Handle GHC-specific character encoding flags, allowing us to control how
   -- GHC produces output regardless of OS.
   env <- getEnvironment
   case lookup "GHC_CHARENC" env of
    Just "UTF-8" -> do
     hSetEncoding stdout utf8
     hSetEncoding stderr utf8
    _ -> do
     -- Avoid GHC erroring out when trying to display unhandled characters
     hSetTranslit stdout
     hSetTranslit stderr
95

Ian Lynagh's avatar
Ian Lynagh committed
96
   GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
97
98
    -- 1. extract the -B flag from the args
    argv0 <- getArgs
99

100
    let (minusB_args, argv1) = partition ("-B" `isPrefixOf`) argv0
101
102
103
        mbMinusB | null minusB_args = Nothing
                 | otherwise = Just (drop 2 (last minusB_args))

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    let argv1' = map (mkGeneralLocated "on the commandline") argv1
    (argv2, staticFlagWarnings) <- parseStaticFlags argv1'

    -- 2. Parse the "mode" flags (--make, --interactive etc.)
    (mode, argv3, modeFlagWarnings) <- parseModeFlags argv2

    let flagWarnings = staticFlagWarnings ++ modeFlagWarnings

    -- If all we want to do is something like showing the version number
    -- then do it now, before we start a GHC session etc. This makes
    -- getting basic information much more resilient.

    -- In particular, if we wait until later before giving the version
    -- number then bootstrapping gets confused, as it tries to find out
    -- what version of GHC it's using before package.conf exists, so
    -- starting the session fails.
    case mode of
        Left preStartupMode ->
            do case preStartupMode of
123
124
125
126
                   ShowSupportedExtensions   -> showSupportedExtensions
                   ShowVersion               -> showVersion
                   ShowNumVersion            -> putStrLn cProjectVersion
                   ShowOptions isInteractive -> showOptions isInteractive
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
        Right postStartupMode ->
            -- start our GHC session
            GHC.runGhc mbMinusB $ do

            dflags <- GHC.getSessionDynFlags

            case postStartupMode of
                Left preLoadMode ->
                    liftIO $ do
                        case preLoadMode of
                            ShowInfo               -> showInfo dflags
                            ShowGhcUsage           -> showGhcUsage  dflags
                            ShowGhciUsage          -> showGhciUsage dflags
                            PrintWithDynFlags f    -> putStrLn (f dflags)
                Right postLoadMode ->
                    main' postLoadMode dflags argv3 flagWarnings

main' :: PostLoadMode -> DynFlags -> [Located String] -> [Located String]
      -> Ghc ()
main' postLoadMode dflags0 args flagWarnings = do
147
148
149
150
151
152
  -- set the default GhcMode, HscTarget and GhcLink.  The HscTarget
  -- can be further adjusted on a module by module basis, using only
  -- the -fvia-C and -fasm flags.  If the default HscTarget is not
  -- HscC or HscAsm, -fvia-C and -fasm have no effect.
  let dflt_target = hscTarget dflags0
      (mode, lang, link)
153
154
155
156
157
         = case postLoadMode of
               DoInteractive   -> (CompManager, HscInterpreted, LinkInMemory)
               DoEval _        -> (CompManager, HscInterpreted, LinkInMemory)
               DoMake          -> (CompManager, dflt_target,    LinkBinary)
               DoMkDependHS    -> (MkDepend,    dflt_target,    LinkBinary)
158
               DoAbiHash       -> (OneShot,     dflt_target,    LinkBinary)
159
               DoMergeRequirements -> (OneShot, dflt_target,    LinkBinary)
160
               _               -> (OneShot,     dflt_target,    LinkBinary)
161

162
163
  let dflags1 = case lang of
                HscInterpreted ->
164
165
166
167
168
169
170
171
172
                    let platform = targetPlatform dflags0
                        dflags0a = updateWays $ dflags0 { ways = interpWays }
                        dflags0b = foldl gopt_set dflags0a
                                 $ concatMap (wayGeneralFlags platform)
                                             interpWays
                        dflags0c = foldl gopt_unset dflags0b
                                 $ concatMap (wayUnsetGeneralFlags platform)
                                             interpWays
                    in dflags0c
173
174
175
                _ ->
                    dflags0
      dflags2 = dflags1{ ghcMode   = mode,
176
                         hscTarget = lang,
177
                         ghcLink   = link,
178
179
180
181
                         verbosity = case postLoadMode of
                                         DoEval _ -> 0
                                         _other   -> 1
                        }
182

183
184
      -- turn on -fimplicit-import-qualified for GHCi now, so that it
      -- can be overriden from the command-line
185
186
      -- XXX: this should really be in the interactive DynFlags, but
      -- we don't set that until later in interactiveUI
187
      dflags3  | DoInteractive <- postLoadMode = imp_qual_enabled
188
               | DoEval _      <- postLoadMode = imp_qual_enabled
189
190
               | otherwise                     = dflags2
        where imp_qual_enabled = dflags2 `gopt_set` Opt_ImplicitImportQualified
191

Thomas Schilling's avatar
Thomas Schilling committed
192
193
        -- The rest of the arguments are "dynamic"
        -- Leftover ones are presumably files
194
  (dflags4, fileish_args, dynamicFlagWarnings) <- GHC.parseDynamicFlags dflags3 args
195

196
  GHC.prettyPrintGhcErrors dflags4 $ do
Ian Lynagh's avatar
Ian Lynagh committed
197

198
  let flagWarnings' = flagWarnings ++ dynamicFlagWarnings
199
200

  handleSourceError (\e -> do
201
202
       GHC.printException e
       liftIO $ exitWith (ExitFailure 1)) $ do
203
         liftIO $ handleFlagWarnings dflags4 flagWarnings'
204

Thomas Schilling's avatar
Thomas Schilling committed
205
        -- make sure we clean up after ourselves
206
  GHC.defaultCleanupHandler dflags4 $ do
207

208
  liftIO $ showBanner postLoadMode dflags4
209

210
  let
dterei's avatar
dterei committed
211
     -- To simplify the handling of filepaths, we normalise all filepaths right
sof's avatar
sof committed
212
     -- away - e.g., for win32 platforms, backslashes are converted
sof's avatar
sof committed
213
     -- into forward slashes.
214
    normal_fileish_paths = map (normalise . unLoc) fileish_args
215
    (srcs, objs)         = partition_args normal_fileish_paths [] []
216

217
218
    dflags5 = dflags4 { ldInputs = map (FileOption "") objs
                                   ++ ldInputs dflags4 }
219
220

  -- we've finished manipulating the DynFlags, update the session
221
222
  _ <- GHC.setSessionDynFlags dflags5
  dflags6 <- GHC.getSessionDynFlags
223
  hsc_env <- GHC.getSession
224

Thomas Schilling's avatar
Thomas Schilling committed
225
        ---------------- Display configuration -----------
Edward Z. Yang's avatar
Edward Z. Yang committed
226
  case verbosity dflags6 of
227
    v | v == 4 -> liftIO $ dumpPackagesSimple dflags6
Edward Z. Yang's avatar
Edward Z. Yang committed
228
229
      | v >= 5 -> liftIO $ dumpPackages dflags6
      | otherwise -> return ()
230

231
  when (verbosity dflags6 >= 3) $ do
Thomas Schilling's avatar
Thomas Schilling committed
232
        liftIO $ hPutStrLn stderr ("Hsc static flags: " ++ unwords staticFlags)
233

234
235
236
237
238

  when (dopt Opt_D_dump_mod_map dflags6) . liftIO $
    printInfoForUser (dflags6 { pprCols = 200 })
                     (pkgQual dflags6) (pprModuleMap dflags6)

Thomas Schilling's avatar
Thomas Schilling committed
239
        ---------------- Final sanity checking -----------
240
  liftIO $ checkOptions postLoadMode dflags6 srcs objs
241

Ian Lynagh's avatar
Ian Lynagh committed
242
  ---------------- Do the business -----------
Thomas Schilling's avatar
Thomas Schilling committed
243
  handleSourceError (\e -> do
244
       GHC.printException e
245
       liftIO $ exitWith (ExitFailure 1)) $ do
246
    case postLoadMode of
247
       ShowInterface f        -> liftIO $ doShowIface dflags6 f
Thomas Schilling's avatar
Thomas Schilling committed
248
       DoMake                 -> doMake srcs
249
250
       DoMkDependHS           -> doMkDependHS (map fst srcs)
       StopBefore p           -> liftIO (oneShot hsc_env p srcs)
251
252
       DoInteractive          -> ghciUI srcs Nothing
       DoEval exprs           -> ghciUI srcs $ Just $ reverse exprs
253
       DoAbiHash              -> abiHash (map fst srcs)
254
       DoMergeRequirements           -> doMergeRequirements (map fst srcs)
255
       ShowPackages           -> liftIO $ showPackages dflags6
Thomas Schilling's avatar
Thomas Schilling committed
256

257
  liftIO $ dumpFinalStats dflags6
258

259
ghciUI :: [(FilePath, Maybe Phase)] -> Maybe [String] -> Ghc ()
260
#ifndef GHCI
261
ghciUI _ _ = throwGhcException (CmdLineError "not built for interactive use")
262
263
#else
ghciUI     = interactiveUI defaultGhciSettings
264
265
#endif

266
267
268
269
270
-- -----------------------------------------------------------------------------
-- Splitting arguments into source files and object files.  This is where we
-- interpret the -x <suffix> option, and attach a (Maybe Phase) to each source
-- file indicating the phase specified by the -x option in force, if any.

Ian Lynagh's avatar
Ian Lynagh committed
271
272
partition_args :: [String] -> [(String, Maybe Phase)] -> [String]
               -> ([(String, Maybe Phase)], [String])
273
274
partition_args [] srcs objs = (reverse srcs, reverse objs)
partition_args ("-x":suff:args) srcs objs
dterei's avatar
dterei committed
275
276
277
278
279
280
  | "none" <- suff      = partition_args args srcs objs
  | StopLn <- phase     = partition_args args srcs (slurp ++ objs)
  | otherwise           = partition_args rest (these_srcs ++ srcs) objs
        where phase = startPhase suff
              (slurp,rest) = break (== "-x") args
              these_srcs = zip slurp (repeat (Just phase))
281
282
283
284
285
286
partition_args (arg:args) srcs objs
  | looks_like_an_input arg = partition_args args ((arg,Nothing):srcs) objs
  | otherwise               = partition_args args srcs (arg:objs)

    {-
      We split out the object files (.o, .dll) and add them
287
      to ldInputs for use by the linker.
288
289
290

      The following things should be considered compilation manager inputs:

dterei's avatar
dterei committed
291
       - haskell source files (strings ending in .hs, .lhs or other
292
293
294
295
         haskellish extension),

       - module names (not forgetting hierarchical module names),

Simon Marlow's avatar
Simon Marlow committed
296
297
298
299
       - things beginning with '-' are flags that were not recognised by
         the flag parser, and we want them to generate errors later in
         checkOptions, so we class them as source files (#5921)

300
301
302
303
304
305
       - and finally we consider everything not containing a '.' to be
         a comp manager input, as shorthand for a .hs or .lhs filename.

      Everything else is considered to be a linker object, and passed
      straight through to the linker.
    -}
Ian Lynagh's avatar
Ian Lynagh committed
306
looks_like_an_input :: String -> Bool
dterei's avatar
dterei committed
307
looks_like_an_input m =  isSourceFilename m
dterei's avatar
dterei committed
308
                      || looksLikeModuleName m
Simon Marlow's avatar
Simon Marlow committed
309
                      || "-" `isPrefixOf` m
dterei's avatar
dterei committed
310
                      || '.' `notElem` m
311

312
313
314
-- -----------------------------------------------------------------------------
-- Option sanity checks

Thomas Schilling's avatar
Thomas Schilling committed
315
316
317
-- | Ensure sanity of options.
--
-- Throws 'UsageError' or 'CmdLineError' if not.
318
checkOptions :: PostLoadMode -> DynFlags -> [(String,Maybe Phase)] -> [String] -> IO ()
319
     -- Final sanity checking before kicking off a compilation (pipeline).
320
checkOptions mode dflags srcs objs = do
ross's avatar
ross committed
321
     -- Complain about any unknown flags
322
   let unknown_opts = [ f | (f@('-':_), _) <- srcs ]
ross's avatar
ross committed
323
324
   when (notNull unknown_opts) (unknownFlagsErr unknown_opts)

325
   when (notNull (filter wayRTSOnly (ways dflags))
326
         && isInterpretiveMode mode) $
327
        hPutStrLn stderr ("Warning: -debug, -threaded and -ticky are ignored by GHCi")
328

dterei's avatar
dterei committed
329
        -- -prof and --interactive are not a good combination
330
   when ((filter (not . wayRTSOnly) (ways dflags) /= interpWays)
331
         && isInterpretiveMode mode) $
332
      do throwGhcException (UsageError
333
                   "--interactive can't be used with -prof or -static.")
dterei's avatar
dterei committed
334
        -- -ohi sanity check
dterei's avatar
dterei committed
335
   if (isJust (outputHi dflags) &&
336
      (isCompManagerMode mode || srcs `lengthExceeds` 1))
337
        then throwGhcException (UsageError "-ohi can only be used when compiling a single source file")
dterei's avatar
dterei committed
338
        else do
339

dterei's avatar
dterei committed
340
        -- -o sanity checking
341
   if (srcs `lengthExceeds` 1 && isJust (outputFile dflags)
dterei's avatar
dterei committed
342
         && not (isLinkMode mode))
343
        then throwGhcException (UsageError "can't apply -o to multiple source files")
dterei's avatar
dterei committed
344
        else do
345

346
   let not_linking = not (isLinkMode mode) || isNoLink (ghcLink dflags)
347
348
349
350

   when (not_linking && not (null objs)) $
        hPutStrLn stderr ("Warning: the following files would be used as linker inputs, but linking is not being done: " ++ unwords objs)

dterei's avatar
dterei committed
351
352
        -- Check that there are some input files
        -- (except in the interactive case)
353
   if null srcs && (null objs || not_linking) && needsInputsMode mode
354
        then throwGhcException (UsageError "no input files")
dterei's avatar
dterei committed
355
        else do
356

357
358
359
360
361
362
   case mode of
      StopBefore HCc | hscTarget dflags /= HscC
        -> throwGhcException $ UsageError $
           "the option -C is only available with an unregisterised GHC"
      _ -> return ()

363
     -- Verify that output files point somewhere sensible.
364
365
366
367
   verifyOutputFiles dflags

-- Compiler output options

368
-- Called to verify that the output files point somewhere valid.
369
370
371
372
--
-- The assumption is that the directory portion of these output
-- options will have to exist by the time 'verifyOutputFiles'
-- is invoked.
dterei's avatar
dterei committed
373
--
374
375
-- We create the directories for -odir, -hidir, -outputdir etc. ourselves if
-- they don't exist, so don't check for those here (#2278).
376
377
378
379
380
381
382
383
384
385
386
387
388
verifyOutputFiles :: DynFlags -> IO ()
verifyOutputFiles dflags = do
  let ofile = outputFile dflags
  when (isJust ofile) $ do
     let fn = fromJust ofile
     flg <- doesDirNameExist fn
     when (not flg) (nonExistentDir "-o" fn)
  let ohi = outputHi dflags
  when (isJust ohi) $ do
     let hi = fromJust ohi
     flg <- doesDirNameExist hi
     when (not flg) (nonExistentDir "-ohi" hi)
 where
dterei's avatar
dterei committed
389
   nonExistentDir flg dir =
390
     throwGhcException (CmdLineError ("error: directory portion of " ++
dterei's avatar
dterei committed
391
                             show dir ++ " does not exist (used with " ++
dterei's avatar
dterei committed
392
                             show flg ++ " option.)"))
393
394
395
396

-----------------------------------------------------------------------------
-- GHC modes of operation

397
398
399
400
type Mode = Either PreStartupMode PostStartupMode
type PostStartupMode = Either PreLoadMode PostLoadMode

data PreStartupMode
401
402
403
404
  = ShowVersion                          -- ghc -V/--version
  | ShowNumVersion                       -- ghc --numeric-version
  | ShowSupportedExtensions              -- ghc --supported-extensions
  | ShowOptions Bool {- isInteractive -} -- ghc --show-options
405

406
showVersionMode, showNumVersionMode, showSupportedExtensionsMode, showOptionsMode :: Mode
407
408
409
showVersionMode             = mkPreStartupMode ShowVersion
showNumVersionMode          = mkPreStartupMode ShowNumVersion
showSupportedExtensionsMode = mkPreStartupMode ShowSupportedExtensions
410
showOptionsMode             = mkPreStartupMode (ShowOptions False)
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

mkPreStartupMode :: PreStartupMode -> Mode
mkPreStartupMode = Left

isShowVersionMode :: Mode -> Bool
isShowVersionMode (Left ShowVersion) = True
isShowVersionMode _ = False

isShowNumVersionMode :: Mode -> Bool
isShowNumVersionMode (Left ShowNumVersion) = True
isShowNumVersionMode _ = False

data PreLoadMode
  = ShowGhcUsage                           -- ghc -?
  | ShowGhciUsage                          -- ghci -?
  | ShowInfo                               -- ghc --info
  | PrintWithDynFlags (DynFlags -> String) -- ghc --print-foo

showGhcUsageMode, showGhciUsageMode, showInfoMode :: Mode
showGhcUsageMode = mkPreLoadMode ShowGhcUsage
showGhciUsageMode = mkPreLoadMode ShowGhciUsage
showInfoMode = mkPreLoadMode ShowInfo

434
435
436
437
printSetting :: String -> Mode
printSetting k = mkPreLoadMode (PrintWithDynFlags f)
    where f dflags = fromMaybe (panic ("Setting not found: " ++ show k))
                   $ lookup k (compilerInfo dflags)
438
439
440
441
442
443
444
445
446
447
448

mkPreLoadMode :: PreLoadMode -> Mode
mkPreLoadMode = Right . Left

isShowGhcUsageMode :: Mode -> Bool
isShowGhcUsageMode (Right (Left ShowGhcUsage)) = True
isShowGhcUsageMode _ = False

isShowGhciUsageMode :: Mode -> Bool
isShowGhciUsageMode (Right (Left ShowGhciUsage)) = True
isShowGhciUsageMode _ = False
449

450
451
data PostLoadMode
  = ShowInterface FilePath  -- ghc --show-iface
Ian Lynagh's avatar
Ian Lynagh committed
452
453
454
455
456
  | DoMkDependHS            -- ghc -M
  | StopBefore Phase        -- ghc -E | -C | -S
                            -- StopBefore StopLn is the default
  | DoMake                  -- ghc --make
  | DoInteractive           -- ghc --interactive
Ian Lynagh's avatar
Ian Lynagh committed
457
  | DoEval [String]         -- ghc -e foo -e bar => DoEval ["bar", "foo"]
458
  | DoAbiHash               -- ghc --abi-hash
459
  | ShowPackages            -- ghc --show-packages
460
  | DoMergeRequirements            -- ghc --merge-requirements
461

462
doMkDependHSMode, doMakeMode, doInteractiveMode,
463
  doAbiHashMode, showPackagesMode, doMergeRequirementsMode :: Mode
464
465
466
doMkDependHSMode = mkPostLoadMode DoMkDependHS
doMakeMode = mkPostLoadMode DoMake
doInteractiveMode = mkPostLoadMode DoInteractive
467
doAbiHashMode = mkPostLoadMode DoAbiHash
468
showPackagesMode = mkPostLoadMode ShowPackages
469
doMergeRequirementsMode = mkPostLoadMode DoMergeRequirements
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

showInterfaceMode :: FilePath -> Mode
showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)

stopBeforeMode :: Phase -> Mode
stopBeforeMode phase = mkPostLoadMode (StopBefore phase)

doEvalMode :: String -> Mode
doEvalMode str = mkPostLoadMode (DoEval [str])

mkPostLoadMode :: PostLoadMode -> Mode
mkPostLoadMode = Right . Right

isDoInteractiveMode :: Mode -> Bool
isDoInteractiveMode (Right (Right DoInteractive)) = True
isDoInteractiveMode _ = False
486

487
488
489
490
491
492
493
494
isStopLnMode :: Mode -> Bool
isStopLnMode (Right (Right (StopBefore StopLn))) = True
isStopLnMode _ = False

isDoMakeMode :: Mode -> Bool
isDoMakeMode (Right (Right DoMake)) = True
isDoMakeMode _ = False

495
496
497
498
isDoEvalMode :: Mode -> Bool
isDoEvalMode (Right (Right (DoEval _))) = True
isDoEvalMode _ = False

Ian Lynagh's avatar
Ian Lynagh committed
499
#ifdef GHCI
500
isInteractiveMode :: PostLoadMode -> Bool
501
isInteractiveMode DoInteractive = True
dterei's avatar
dterei committed
502
isInteractiveMode _             = False
Ian Lynagh's avatar
Ian Lynagh committed
503
#endif
504
505

-- isInterpretiveMode: byte-code compiler involved
506
isInterpretiveMode :: PostLoadMode -> Bool
507
508
509
510
isInterpretiveMode DoInteractive = True
isInterpretiveMode (DoEval _)    = True
isInterpretiveMode _             = False

511
needsInputsMode :: PostLoadMode -> Bool
dterei's avatar
dterei committed
512
513
514
515
needsInputsMode DoMkDependHS    = True
needsInputsMode (StopBefore _)  = True
needsInputsMode DoMake          = True
needsInputsMode _               = False
516

517
518
-- True if we are going to attempt to link in this mode.
-- (we might not actually link, depending on the GhcLink flag)
519
isLinkMode :: PostLoadMode -> Bool
520
isLinkMode (StopBefore StopLn) = True
dterei's avatar
dterei committed
521
isLinkMode DoMake              = True
522
523
isLinkMode DoInteractive       = True
isLinkMode (DoEval _)          = True
dterei's avatar
dterei committed
524
isLinkMode _                   = False
525

526
isCompManagerMode :: PostLoadMode -> Bool
527
528
529
530
531
532
533
534
isCompManagerMode DoMake        = True
isCompManagerMode DoInteractive = True
isCompManagerMode (DoEval _)    = True
isCompManagerMode _             = False

-- -----------------------------------------------------------------------------
-- Parsing the mode flag

535
parseModeFlags :: [Located String]
536
               -> IO (Mode,
537
538
                      [Located String],
                      [Located String])
539
parseModeFlags args = do
540
  let ((leftover, errs1, warns), (mModeFlag, errs2, flags')) =
541
          runCmdLine (processArgs mode_flags args)
542
543
                     (Nothing, [], [])
      mode = case mModeFlag of
544
             Nothing     -> doMakeMode
545
             Just (m, _) -> m
546
547
548
549
550

  -- See Note [Handling errors when parsing commandline flags]
  unless (null errs1 && null errs2) $ throwGhcException $ errorsToGhcException $
      map (("on the commandline", )) $ map unLoc errs1 ++ errs2

551
  return (mode, flags' ++ leftover, warns)
552

553
type ModeM = CmdLineP (Maybe (Mode, String), [String], [Located String])
554
555
556
  -- mode flags sometimes give rise to new DynFlags (eg. -C, see below)
  -- so we collect the new ones and return them.

557
mode_flags :: [Flag ModeM]
558
559
mode_flags =
  [  ------- help / version ----------------------------------------------
560
561
562
563
564
565
566
567
568
569
    defFlag "?"                     (PassFlag (setMode showGhcUsageMode))
  , defFlag "-help"                 (PassFlag (setMode showGhcUsageMode))
  , defFlag "V"                     (PassFlag (setMode showVersionMode))
  , defFlag "-version"              (PassFlag (setMode showVersionMode))
  , defFlag "-numeric-version"      (PassFlag (setMode showNumVersionMode))
  , defFlag "-info"                 (PassFlag (setMode showInfoMode))
  , defFlag "-show-options"         (PassFlag (setMode showOptionsMode))
  , defFlag "-supported-languages"  (PassFlag (setMode showSupportedExtensionsMode))
  , defFlag "-supported-extensions" (PassFlag (setMode showSupportedExtensionsMode))
  , defFlag "-show-packages"        (PassFlag (setMode showPackagesMode))
570
  ] ++
571
  [ defFlag k'                      (PassFlag (setMode (printSetting k)))
572
  | k <- ["Project version",
573
          "Project Git commit id",
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
          "Booter version",
          "Stage",
          "Build platform",
          "Host platform",
          "Target platform",
          "Have interpreter",
          "Object splitting supported",
          "Have native code generator",
          "Support SMP",
          "Unregisterised",
          "Tables next to code",
          "RTS ways",
          "Leading underscore",
          "Debug on",
          "LibDir",
          "Global Package DB",
          "C compiler flags",
          "Gcc Linker flags",
          "Ld Linker flags"],
593
594
595
596
    let k' = "-print-" ++ map (replaceSpace . toLower) k
        replaceSpace ' ' = '-'
        replaceSpace c   = c
  ] ++
597
      ------- interfaces ----------------------------------------------------
598
  [ defFlag "-show-iface"  (HasArg (\f -> setMode (showInterfaceMode f)
599
                                               "--show-iface"))
600
601

      ------- primary modes ------------------------------------------------
602
603
604
605
606
607
608
  , defFlag "c"            (PassFlag (\f -> do setMode (stopBeforeMode StopLn) f
                                               addFlag "-no-link" f))
  , defFlag "M"            (PassFlag (setMode doMkDependHSMode))
  , defFlag "E"            (PassFlag (setMode (stopBeforeMode anyHsc)))
  , defFlag "C"            (PassFlag (setMode (stopBeforeMode HCc)))
  , defFlag "S"            (PassFlag (setMode (stopBeforeMode (As False))))
  , defFlag "-make"        (PassFlag (setMode doMakeMode))
609
  , defFlag "-merge-requirements" (PassFlag (setMode doMergeRequirementsMode))
610
611
612
  , defFlag "-interactive" (PassFlag (setMode doInteractiveMode))
  , defFlag "-abi-hash"    (PassFlag (setMode doAbiHashMode))
  , defFlag "e"            (SepArg   (\s -> setMode (doEvalMode s) "-e"))
613
614
  ]

615
616
setMode :: Mode -> String -> EwM ModeM ()
setMode newMode newFlag = liftEwM $ do
617
618
619
620
621
622
    (mModeFlag, errs, flags') <- getCmdLineState
    let (modeFlag', errs') =
            case mModeFlag of
            Nothing -> ((newMode, newFlag), errs)
            Just (oldMode, oldFlag) ->
                case (oldMode, newMode) of
623
624
625
626
627
                    -- -c/--make are allowed together, and mean --make -no-link
                    _ |  isStopLnMode oldMode && isDoMakeMode newMode
                      || isStopLnMode newMode && isDoMakeMode oldMode ->
                      ((doMakeMode, "--make"), [])

628
629
630
631
632
633
634
635
                    -- If we have both --help and --interactive then we
                    -- want showGhciUsage
                    _ | isShowGhcUsageMode oldMode &&
                        isDoInteractiveMode newMode ->
                            ((showGhciUsageMode, oldFlag), [])
                      | isShowGhcUsageMode newMode &&
                        isDoInteractiveMode oldMode ->
                            ((showGhciUsageMode, newFlag), [])
636
637
638
639
640
641
642
643
644

                    -- If we have both -e and --interactive then -e always wins
                    _ | isDoEvalMode oldMode &&
                        isDoInteractiveMode newMode ->
                            ((oldMode, oldFlag), [])
                      | isDoEvalMode newMode &&
                        isDoInteractiveMode oldMode ->
                            ((newMode, newFlag), [])

645
646
647
648
649
650
651
652
653
654
                    -- Otherwise, --help/--version/--numeric-version always win
                      | isDominantFlag oldMode -> ((oldMode, oldFlag), [])
                      | isDominantFlag newMode -> ((newMode, newFlag), [])
                    -- We need to accumulate eval flags like "-e foo -e bar"
                    (Right (Right (DoEval esOld)),
                     Right (Right (DoEval [eNew]))) ->
                        ((Right (Right (DoEval (eNew : esOld))), oldFlag),
                         errs)
                    -- Saying e.g. --interactive --interactive is OK
                    _ | oldFlag == newFlag -> ((oldMode, oldFlag), errs)
655
656
657
658
659
660
661
662

                    -- --interactive and --show-options are used together
                    (Right (Right DoInteractive), Left (ShowOptions _)) ->
                      ((Left (ShowOptions True),
                        "--interactive --show-options"), errs)
                    (Left (ShowOptions _), (Right (Right DoInteractive))) ->
                      ((Left (ShowOptions True),
                        "--show-options --interactive"), errs)
663
664
665
666
667
668
669
670
671
672
673
674
675
                    -- Otherwise, complain
                    _ -> let err = flagMismatchErr oldFlag newFlag
                         in ((oldMode, oldFlag), err : errs)
    putCmdLineState (Just modeFlag', errs', flags')
  where isDominantFlag f = isShowGhcUsageMode   f ||
                           isShowGhciUsageMode  f ||
                           isShowVersionMode    f ||
                           isShowNumVersionMode f

flagMismatchErr :: String -> String -> String
flagMismatchErr oldFlag newFlag
    = "cannot use `" ++ oldFlag ++  "' with `" ++ newFlag ++ "'"

676
677
addFlag :: String -> String -> EwM ModeM ()
addFlag s flag = liftEwM $ do
678
679
680
  (m, e, flags') <- getCmdLineState
  putCmdLineState (m, e, mkGeneralLocated loc s : flags')
    where loc = "addFlag by " ++ flag ++ " on the commandline"
681

682
683
684
-- ----------------------------------------------------------------------------
-- Run --make mode

Thomas Schilling's avatar
Thomas Schilling committed
685
686
doMake :: [(String,Maybe Phase)] -> Ghc ()
doMake srcs  = do
687
688
    let (hs_srcs, non_hs_srcs) = partition haskellish srcs

dterei's avatar
dterei committed
689
        haskellish (f,Nothing) =
690
          looksLikeModuleName f || isHaskellSrcFilename f || '.' `notElem` f
dterei's avatar
dterei committed
691
        haskellish (_,Just phase) =
thomie's avatar
thomie committed
692
          phase `notElem` [ As True, As False, Cc, Cobjc, Cobjcxx, CmmCpp, Cmm
Simon Marlow's avatar
Simon Marlow committed
693
                          , StopLn]
694

Thomas Schilling's avatar
Thomas Schilling committed
695
    hsc_env <- GHC.getSession
696
697
698
699
700
701

    -- if we have no haskell sources from which to do a dependency
    -- analysis, then just do one-shot compilation and/or linking.
    -- This means that "ghc Foo.o Bar.o -o baz" links the program as
    -- we expect.
    if (null hs_srcs)
702
       then liftIO (oneShot hsc_env StopLn srcs)
703
704
       else do

705
    o_files <- mapM (\x -> liftIO $ compileFile hsc_env StopLn x)
Thomas Schilling's avatar
Thomas Schilling committed
706
                 non_hs_srcs
707
    dflags <- GHC.getSessionDynFlags
708
709
    let dflags' = dflags { ldInputs = map (FileOption "") o_files
                                      ++ ldInputs dflags }
710
    _ <- GHC.setSessionDynFlags dflags'
711
712

    targets <- mapM (uncurry GHC.guessTarget) hs_srcs
Thomas Schilling's avatar
Thomas Schilling committed
713
714
715
716
    GHC.setTargets targets
    ok_flag <- GHC.load LoadAllTargets

    when (failed ok_flag) (liftIO $ exitWith (ExitFailure 1))
717
718
    return ()

719
720
721
722
723
724
725
726
727
728
-- ----------------------------------------------------------------------------
-- Run --merge-requirements mode

doMergeRequirements :: [String] -> Ghc ()
doMergeRequirements srcs = mapM_ doMergeRequirement srcs

doMergeRequirement :: String -> Ghc ()
doMergeRequirement src = do
    hsc_env <- getSession
    liftIO $ mergeRequirement hsc_env (mkModuleName src)
729
730
731
732
733
734

-- ---------------------------------------------------------------------------
-- --show-iface mode

doShowIface :: DynFlags -> FilePath -> IO ()
doShowIface dflags file = do
735
  hsc_env <- newHscEnv dflags
736
737
  showIface hsc_env file

738
739
-- ---------------------------------------------------------------------------
-- Various banners and verbosity output.
740

741
742
showBanner :: PostLoadMode -> DynFlags -> IO ()
showBanner _postLoadMode dflags = do
743
   let verb = verbosity dflags
Ian Lynagh's avatar
Ian Lynagh committed
744

745
746
#ifdef GHCI
   -- Show the GHCi banner
747
   when (isInteractiveMode _postLoadMode && verb >= 1) $ putStrLn ghciWelcomeMsg
748
749
#endif

Ian Lynagh's avatar
Ian Lynagh committed
750
751
752
753
   -- Display details of the configuration in verbose mode
   when (verb >= 2) $
    do hPutStr stderr "Glasgow Haskell Compiler, Version "
       hPutStr stderr cProjectVersion
Ian Lynagh's avatar
Ian Lynagh committed
754
       hPutStr stderr ", stage "
Ian Lynagh's avatar
Ian Lynagh committed
755
756
757
       hPutStr stderr cStage
       hPutStr stderr " booted by GHC version "
       hPutStrLn stderr cBooterVersion
758

759
760
-- We print out a Read-friendly string, but a prettier one than the
-- Show instance gives us
761
762
763
showInfo :: DynFlags -> IO ()
showInfo dflags = do
        let sq x = " [" ++ x ++ "\n ]"
764
        putStrLn $ sq $ intercalate "\n ," $ map show $ compilerInfo dflags
765

766
showSupportedExtensions :: IO ()
767
showSupportedExtensions = mapM_ putStrLn supportedLanguagesAndExtensions
Ian Lynagh's avatar
Ian Lynagh committed
768

769
showVersion :: IO ()
770
771
showVersion = putStrLn (cProjectName ++ ", version " ++ cProjectVersion)

772
773
showOptions :: Bool -> IO ()
showOptions isInteractive = putStr (unlines availableOptions)
774
    where
775
776
777
778
779
780
781
782
783
      availableOptions = concat [
        flagsForCompletion isInteractive,
        map ('-':) (concat [
            getFlagNames mode_flags
          , (filterUnwantedStatic . getFlagNames $ flagsStatic)
          , flagsStaticNames
          ])
        ]
      getFlagNames opts         = map flagName opts
784
785
786
      -- this is a hack to get rid of two unwanted entries that get listed
      -- as static flags. Hopefully this hack will disappear one day together
      -- with static flags
787
      filterUnwantedStatic      = filter (`notElem`["f", "fno-"])
788

789
790
791
792
793
794
795
796
797
798
showGhcUsage :: DynFlags -> IO ()
showGhcUsage = showUsage False

showGhciUsage :: DynFlags -> IO ()
showGhciUsage = showUsage True

showUsage :: Bool -> DynFlags -> IO ()
showUsage ghci dflags = do
  let usage_path = if ghci then ghciUsagePath dflags
                           else ghcUsagePath dflags
799
800
801
  usage <- readFile usage_path
  dump usage
  where
802
     dump ""          = return ()
803
     dump ('$':'$':s) = putStr progName >> dump s
804
     dump (c:s)       = putChar c >> dump s
805

806
dumpFinalStats :: DynFlags -> IO ()
dterei's avatar
dterei committed
807
dumpFinalStats dflags =
ian@well-typed.com's avatar
ian@well-typed.com committed
808
  when (gopt Opt_D_faststring_stats dflags) $ dumpFastStringStats dflags
809
810
811
812

dumpFastStringStats :: DynFlags -> IO ()
dumpFastStringStats dflags = do
  buckets <- getFastStringTable
Ian Lynagh's avatar
Ian Lynagh committed
813
  let (entries, longest, has_z) = countFS 0 0 0 buckets
814
      msg = text "FastString stats:" $$
dterei's avatar
dterei committed
815
816
817
818
819
820
821
822
823
824
            nest 4 (vcat [text "size:           " <+> int (length buckets),
                          text "entries:        " <+> int entries,
                          text "longest chain:  " <+> int longest,
                          text "has z-encoding: " <+> (has_z `pcntOf` entries)
                         ])
        -- we usually get more "has z-encoding" than "z-encoded", because
        -- when we z-encode a string it might hash to the exact same string,
        -- which will is not counted as "z-encoded".  Only strings whose
        -- Z-encoding is different from the original string are counted in
        -- the "z-encoded" total.
825
826
827
  putMsg dflags msg
  where
   x `pcntOf` y = int ((x * 100) `quot` y) <> char '%'
Ian Lynagh's avatar
Ian Lynagh committed
828

Ian Lynagh's avatar
Ian Lynagh committed
829
830
831
countFS :: Int -> Int -> Int -> [[FastString]] -> (Int, Int, Int)
countFS entries longest has_z [] = (entries, longest, has_z)
countFS entries longest has_z (b:bs) =
832
  let
dterei's avatar
dterei committed
833
834
835
836
        len = length b
        longest' = max len longest
        entries' = entries + len
        has_zs = length (filter hasZEncoding b)
837
  in
Ian Lynagh's avatar
Ian Lynagh committed
838
        countFS entries' longest' (has_z + has_zs) bs
839

840
841
842
843
844
showPackages, dumpPackages, dumpPackagesSimple :: DynFlags -> IO ()
showPackages       dflags = putStrLn (showSDoc dflags (pprPackages dflags))
dumpPackages       dflags = putMsg dflags (pprPackages dflags)
dumpPackagesSimple dflags = putMsg dflags (pprPackagesSimple dflags)

845
846
847
848
849
850
851
852
853
854
-- -----------------------------------------------------------------------------
-- ABI hash support

{-
        ghc --abi-hash Data.Foo System.Bar

Generates a combined hash of the ABI for modules Data.Foo and
System.Bar.  The modules must already be compiled, and appropriate -i
options may be necessary in order to find the .hi files.

855
856
This is used by Cabal for generating the ComponentId for a
package.  The ComponentId must change when the visible ABI of
857
858
859
860
the package chagnes, so during registration Cabal calls ghc --abi-hash
to get a hash of the package's ABI.
-}

861
862
863
864
865
866
867
-- | Print ABI hash of input modules.
--
-- The resulting hash is the MD5 of the GHC version used (Trac #5328,
-- see 'hiVersion') and of the existing ABI hash from each module (see
-- 'mi_mod_hash').
abiHash :: [String] -- ^ List of module names
        -> Ghc ()
868
869
870
871
872
873
874
875
876
877
abiHash strs = do
  hsc_env <- getSession
  let dflags = hsc_dflags hsc_env

  liftIO $ do

  let find_it str = do
         let modname = mkModuleName str
         r <- findImportedModule hsc_env modname Nothing
         case r of
878
           Found _ m -> return m
879
           _error    -> throwGhcException $ CmdLineError $ showSDoc dflags $
880
881
                          cannotFindInterface dflags modname r

882
  mods <- mapM find_it strs
883

Simon Marlow's avatar
Simon Marlow committed
884
  let get_iface modl = loadUserInterface False (text "abiHash") modl
885
886
887
  ifaces <- initIfaceCheck hsc_env $ mapM get_iface mods

  bh <- openBinMem (3*1024) -- just less than a block
Ian Lynagh's avatar
Ian Lynagh committed
888
  put_ bh hiVersion
889
890
    -- package hashes change when the compiler version changes (for now)
    -- see #5328
891
892
893
  mapM_ (put_ bh . mi_mod_hash) ifaces
  f <- fingerprintBinMem bh

Ian Lynagh's avatar
Ian Lynagh committed
894
  putStrLn (showPpr dflags f)
895

896
897
898
899
-- -----------------------------------------------------------------------------
-- Util

unknownFlagsErr :: [String] -> a
900
unknownFlagsErr fs = throwGhcException $ UsageError $ concatMap oneError fs
901
902
903
904
905
  where
    oneError f =
        "unrecognised flag: " ++ f ++ "\n" ++
        (case fuzzyMatch f (nub allFlags) of
            [] -> ""
906
            suggs -> "did you mean one of:\n" ++ unlines (map ("  " ++) suggs))
Austin Seipp's avatar
Austin Seipp committed
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921

{- Note [-Bsymbolic and hooks]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Bsymbolic is a flag that prevents the binding of references to global
symbols to symbols outside the shared library being compiled (see `man
ld`). When dynamically linking, we don't use -Bsymbolic on the RTS
package: that is because we want hooks to be overridden by the user,
we don't want to constrain them to the RTS package.

Unfortunately this seems to have broken somehow on OS X: as a result,
defaultHooks (in hschooks.c) is not called, which does not initialize
the GC stats. As a result, this breaks things like `:set +s` in GHCi
(#8754). As a hacky workaround, we instead call 'defaultHooks'
directly to initalize the flags in the RTS.

Gabor Greif's avatar
Gabor Greif committed
922
A byproduct of this, I believe, is that hooks are likely broken on OS
Austin Seipp's avatar
Austin Seipp committed
923
924
925
926
927
928
929
X when dynamically linking. But this probably doesn't affect most
people since we're linking GHC dynamically, but most things themselves
link statically.
-}

foreign import ccall safe "initGCStatistics"
  initGCStatistics :: IO ()