Main.hs 10.8 KB
Newer Older
1 2
{-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}

3
-----------------------------------------------------------------------------
4
-- $Id: Main.hs,v 1.144 2005/01/28 12:55:38 simonmar Exp $
5 6 7
--
-- GHC Driver program
--
8
-- (c) The University of Glasgow 2002
9 10 11 12 13
--
-----------------------------------------------------------------------------

module Main (main) where

14 15
#include "HsVersions.h"

16
#ifdef GHCI
17
import InteractiveUI( ghciWelcomeMsg, interactiveUI )
18 19
#endif

20

21
import CompManager	( cmInit, cmLoadModules, cmDepAnal )
22
import HscTypes		( GhciMode(..) )
23
import Config		( cBooterVersion, cGhcUnregisterised, cProjectVersion )
24
import SysTools		( initSysTools, cleanTempFiles, normalisePath )
25
import Packages		( dumpPackages, initPackages, haskell98PackageId, PackageIdH(..) )
26 27 28 29
import DriverPipeline	( staticLink, doMkDLL, compileFile )
import DriverState	( isLinkMode, isMakeMode, isInteractiveMode,
			  isCompManagerMode, isInterpretiveMode, 
			  buildStgToDo, findBuildTag, unregFlags, 
30
			  v_GhcMode, v_GhcModeFlag, GhcMode(..),
31
			  v_Keep_tmp_files, v_Ld_inputs, v_Ways, 
32
			  v_Output_file, v_Output_hi, 
33
			  verifyOutputFiles, v_NoLink
34
			)
35
import DriverFlags
36

37
import DriverMkDepend	( doMkDependHS )
38
import DriverPhases	( isSourceFilename )
39

40
import DriverUtil	( add, handle, handleDyn, later, unknownFlagsErr )
41
import CmdLineOpts	( DynFlags(..), HscTarget(..), v_Static_hsc_opts,
42
			  defaultDynFlags )
43
import BasicTypes	( failed )
44
import Outputable
45
import Util
46
import Panic		( GhcException(..), panic, installSignalHandlers )
47

48 49
import DATA_IOREF	( readIORef, writeIORef )
import EXCEPTION	( throwDyn, Exception(..), 
50
			  AsyncException(StackOverflow) )
51

52 53 54 55 56 57 58 59
-- Standard Haskell libraries
import IO
import Directory	( doesFileExist )
import System		( getArgs, exitWith, ExitCode(..) )
import Monad
import List
import Maybe

60 61 62 63 64 65 66 67 68 69 70
-----------------------------------------------------------------------------
-- ToDo:

-- new mkdependHS doesn't support all the options that the old one did (-X et al.)
-- time commands when run with -v
-- split marker
-- java generation
-- user ways
-- Win32 support: proper signal handling
-- make sure OPTIONS in .hs file propogate to .hc file if -C or -keep-hc-file-too
-- reading the package configuration file is too slow
71
-- -K<size>
72 73 74 75 76 77 78 79 80 81 82 83

-----------------------------------------------------------------------------
-- Differences vs. old driver:

-- No more "Enter your Haskell program, end with ^D (on a line of its own):"
-- consistency checking removed (may do this properly later)
-- no -Ofile

-----------------------------------------------------------------------------
-- Main loop

main =
84
  -- top-level exception handler: any unrecognised exception is a compiler bug.
85
  handle (\exception -> do
sof's avatar
sof committed
86
  	   hFlush stdout
87 88
	   case exception of
		-- an IO exception probably isn't our fault, so don't panic
89
		IOException _ ->  hPutStrLn stderr (show exception)
90
		AsyncException StackOverflow ->
91
			hPutStrLn stderr "stack overflow: use +RTS -K<size> to increase it"
92
		_other ->  hPutStr stderr (show (Panic (show exception)))
93 94
	   exitWith (ExitFailure 1)
         ) $ do
95

96
  -- all error messages are propagated as exceptions
sof's avatar
sof committed
97 98 99
  handleDyn (\dyn -> do
  		hFlush stdout
  		case dyn of
sof's avatar
sof committed
100
		     PhaseFailed _ code -> exitWith code
sof's avatar
sof committed
101 102 103
		     Interrupted -> exitWith (ExitFailure 1)
		     _ -> do hPutStrLn stderr (show (dyn :: GhcException))
			     exitWith (ExitFailure 1)
104
	    ) $ do
105

106
   installSignalHandlers
107

108 109 110
   argv <- getArgs
   let (minusB_args, argv') = partition (prefixMatch "-B") argv
   top_dir <- initSysTools minusB_args
111

112
	-- Process all the other arguments, and get the source files
113
   non_static <- processStaticFlags argv'
114
   mode <- readIORef v_GhcMode
115

116 117 118
	-- -O and --interactive are not a good combination
	-- ditto with any kind of way selection
   orig_ways <- readIORef v_Ways
119
   when (notNull orig_ways && isInterpretiveMode mode) $
120
      do throwDyn (UsageError 
121 122
                   "--interactive can't be used with -prof, -ticky, -unreg or -smp.")

123 124 125 126 127 128
	-- Find the build tag, and re-process the build-specific options.
	-- Also add in flags for unregisterised compilation, if 
	-- GhcUnregisterised=YES.
   way_opts <- findBuildTag
   let unreg_opts | cGhcUnregisterised == "YES" = unregFlags
		  | otherwise = []
129
   extra_non_static <- processStaticFlags (unreg_opts ++ way_opts)
130

131
	-- Give the static flags to hsc
132
   static_opts <- buildStaticHscOpts
133
   writeIORef v_Static_hsc_opts static_opts
134

135 136
   -- build the default DynFlags (these may be adjusted on a per
   -- module basis by OPTIONS pragmas and settings in the interpreter).
137

138
   stg_todo  <- buildStgToDo
139

140
   -- set the "global" HscTarget.  The HscTarget can be further adjusted on a module
141
   -- by module basis, using only the -fvia-C and -fasm flags.  If the global
142
   -- HscTarget is not HscC or HscAsm, -fvia-C and -fasm have no effect.
143
   let dflags0 = defaultDynFlags
144 145
   let lang = case mode of 
		 DoInteractive  -> HscInterpreted
146
		 DoEval _	-> HscInterpreted
147
		 _other		-> hscTarget dflags0
148

149
   let dflags1 = dflags0{ stgToDo  = stg_todo,
150
                  	  hscTarget  = lang,
151 152 153
			  -- leave out hscOutName for now
	                  hscOutName = panic "Main.main:hscOutName not set",
		  	  verbosity = case mode of
154 155
				 	 DoEval _ -> 0
				 	 _other   -> 1
156
			}
157

158 159
	-- The rest of the arguments are "dynamic"
	-- Leftover ones are presumably files
160 161 162 163 164 165 166 167 168 169 170
   (dflags2, fileish_args) <- processDynamicFlags 
				(extra_non_static ++ non_static) dflags1

	-- make sure we clean up after ourselves
   later (do  forget_it <- readIORef v_Keep_tmp_files
	      unless forget_it $ do
	      cleanTempFiles dflags2
     ) $ do
	-- exceptions will be blocked while we clean the temporary files,
	-- so there shouldn't be any difficulty if we receive further
	-- signals.
171

172 173 174
	-- Read the package config(s), and process the package-related
	-- command-line flags
   dflags <- initPackages dflags2
175

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
   let
    {-
      We split out the object files (.o, .dll) and add them
      to v_Ld_inputs for use by the linker.

      The following things should be considered compilation manager inputs:

       - haskell source files (strings ending in .hs, .lhs or other 
         haskellish extension),

       - module names (not forgetting hierarchical module names),

       - 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.
    -}
194
    looks_like_an_input m =  isSourceFilename m 
195 196 197
			  || looksLikeModuleName m
			  || '.' `notElem` m

sof's avatar
sof committed
198 199
     -- To simplify the handling of filepaths, we normalise all filepaths right 
     -- away - e.g., for win32 platforms, backslashes are converted
sof's avatar
sof committed
200
     -- into forward slashes.
sof's avatar
sof committed
201 202
    normal_fileish_paths = map normalisePath fileish_args
    (srcs, objs)         = partition looks_like_an_input normal_fileish_paths
203

sof's avatar
sof committed
204 205 206
    -- Note: have v_Ld_inputs maintain the order in which 'objs' occurred on 
    --       the command-line.
   mapM_ (add v_Ld_inputs) (reverse objs)
207 208

	---------------- Display banners and configuration -----------
209
   showBanners mode dflags static_opts
210 211 212 213 214

	---------------- Final sanity checking -----------
   checkOptions mode srcs objs

	---------------- Do the business -----------
215 216 217 218

   -- Always link in the haskell98 package for static linking.  Other
   -- packages have to be specified via the -package flag.
   let link_pkgs
219
	  | ExtPackage h98_id <- haskell98PackageId (pkgState dflags) = [h98_id]
220 221
	  | otherwise = []

222
   case mode of
223
	DoMake 	       -> doMake dflags srcs
224
	DoMkDependHS   -> doMkDependHS dflags srcs 
225 226 227 228
	StopBefore p   -> do { compileFiles mode dflags srcs; return () }
	DoMkDLL	       -> do { o_files <- compileFiles mode dflags srcs; 
			       doMkDLL dflags o_files link_pkgs }
	DoLink	       -> do { o_files <- compileFiles mode dflags srcs; 
229 230
			       omit_linking <- readIORef v_NoLink;
			       when (not omit_linking)
231
				    (staticLink dflags o_files link_pkgs) }
232

233
#ifndef GHCI
234 235 236 237
	DoInteractive -> noInteractiveError
	DoEval _      -> noInteractiveError
     where
       noInteractiveError = throwDyn (CmdLineError "not built for interactive use")
238
#else
239 240
	DoInteractive -> interactiveUI dflags srcs Nothing
	DoEval expr   -> interactiveUI dflags srcs (Just expr)
241 242
#endif

243 244 245
-- -----------------------------------------------------------------------------
-- Option sanity checks

246
checkOptions :: GhcMode -> [String] -> [String] -> IO ()
247
     -- Final sanity checking before kicking off a compilation (pipeline).
248
checkOptions mode srcs objs = do
ross's avatar
ross committed
249 250 251 252
     -- Complain about any unknown flags
   let unknown_opts = [ f | f@('-':_) <- srcs ]
   when (notNull unknown_opts) (unknownFlagsErr unknown_opts)

253 254 255
	-- -ohi sanity check
   ohi <- readIORef v_Output_hi
   if (isJust ohi && 
256
      (isCompManagerMode mode || srcs `lengthExceeds` 1))
257 258 259 260 261
	then throwDyn (UsageError "-ohi can only be used when compiling a single source file")
	else do

	-- -o sanity checking
   o_file <- readIORef v_Output_file
262
   if (srcs `lengthExceeds` 1 && isJust o_file && not (isLinkMode mode))
263 264
	then throwDyn (UsageError "can't apply -o to multiple source files")
	else do
265

266 267 268
	-- Check that there are some input files
	-- (except in the interactive case)
   if null srcs && null objs && not (isInterpretiveMode mode)
269 270 271 272 273 274
	then throwDyn (UsageError "no input files")
	else do

     -- Verify that output files point somewhere sensible.
   verifyOutputFiles

275 276 277
-- -----------------------------------------------------------------------------
-- Compile files in one-shot mode.

278 279
compileFiles :: GhcMode
	     -> DynFlags
280 281
	     -> [String]	-- Source files
	     -> IO [String]	-- Object files
282
compileFiles mode dflags srcs = mapM (compileFile mode dflags) srcs
283 284


285 286 287
-- ----------------------------------------------------------------------------
-- Run --make mode

288 289 290
doMake :: DynFlags -> [String] -> IO ()
doMake dflags []    = throwDyn (UsageError "no input files")
doMake dflags srcs  = do 
291 292 293
    state  <- cmInit Batch dflags
    graph  <- cmDepAnal state srcs
    (_, ok_flag, _) <- cmLoadModules state graph
294 295 296
    when (failed ok_flag) (exitWith (ExitFailure 1))
    return ()

297 298
-- ---------------------------------------------------------------------------
-- Various banners and verbosity output.
299

300 301 302
showBanners :: GhcMode -> DynFlags -> [String] -> IO ()
showBanners mode dflags static_opts = do
   let verb = verbosity dflags
303

304 305
	-- Show the GHCi banner
#  ifdef GHCI
306
   when (isInteractiveMode mode && verb >= 1) $
307 308 309 310
      hPutStrLn stdout ghciWelcomeMsg
#  endif

	-- Display details of the configuration in verbose mode
311 312 313 314 315
   when (verb >= 2) $
	do hPutStr stderr "Glasgow Haskell Compiler, Version "
 	   hPutStr stderr cProjectVersion
	   hPutStr stderr ", for Haskell 98, compiled by GHC version "
	   hPutStrLn stderr cBooterVersion
316

317 318
   when (verb >= 3) $
	dumpPackages dflags
319

320 321
   when (verb >= 3) $
	hPutStrLn stderr ("Hsc static flags: " ++ unwords static_opts)