[project @ 2000-11-13 12:43:20 by sewardj]
[ghc-hetmet.git] / ghc / compiler / main / Main.hs
1 {-# OPTIONS -W -fno-warn-incomplete-patterns #-}
2 -----------------------------------------------------------------------------
3 -- $Id: Main.hs,v 1.20 2000/11/13 12:43:20 sewardj Exp $
4 --
5 -- GHC Driver program
6 --
7 -- (c) Simon Marlow 2000
8 --
9 -----------------------------------------------------------------------------
10
11 -- with path so that ghc -M can find config.h
12 #include "../includes/config.h"
13
14 module Main (main) where
15
16 #include "HsVersions.h"
17
18 import CompManager
19 import DriverPipeline
20 import DriverState
21 import DriverFlags
22 import DriverMkDepend
23 import DriverUtil
24 import DriverPhases     ( Phase(..) )
25 import CmdLineOpts      ( HscLang(..), DynFlags(..), v_Static_hsc_opts )
26 import Module           ( mkModuleName )
27 import TmpFiles
28 import Finder           ( initFinder )
29 import CmStaticInfo
30 import Config
31 import Util
32 import Panic
33
34 import Concurrent
35 #ifndef mingw32_TARGET_OS
36 import Posix
37 #endif
38 import Directory
39 import IOExts
40 import Exception
41 import Dynamic
42
43 import IO
44 import Monad
45 import List
46 import System
47 import Maybe
48
49
50 -----------------------------------------------------------------------------
51 -- Changes:
52
53 -- * -fglasgow-exts NO LONGER IMPLIES -package lang!!!  (-fglasgow-exts is a
54 --   dynamic flag whereas -package is a static flag.)
55
56 -----------------------------------------------------------------------------
57 -- ToDo:
58
59 -- -nohi doesn't work
60 -- new mkdependHS doesn't support all the options that the old one did (-X et al.)
61 -- time commands when run with -v
62 -- split marker
63 -- mkDLL
64 -- java generation
65 -- user ways
66 -- Win32 support: proper signal handling
67 -- make sure OPTIONS in .hs file propogate to .hc file if -C or -keep-hc-file-too
68 -- reading the package configuration file is too slow
69 -- -H, -K, -Rghc-timing
70 -- hi-diffs
71
72 -----------------------------------------------------------------------------
73 -- Differences vs. old driver:
74
75 -- No more "Enter your Haskell program, end with ^D (on a line of its own):"
76 -- consistency checking removed (may do this properly later)
77 -- removed -noC
78 -- no hi diffs (could be added later)
79 -- no -Ofile
80
81 -----------------------------------------------------------------------------
82 -- Main loop
83
84 main =
85   -- all error messages are propagated as exceptions
86   handleDyn (\dyn -> case dyn of
87                           PhaseFailed _phase code -> exitWith code
88                           Interrupted -> exitWith (ExitFailure 1)
89                           _ -> do hPutStrLn stderr (show (dyn :: BarfKind))
90                                   exitWith (ExitFailure 1)
91               ) $ do
92
93    -- make sure we clean up after ourselves
94    later (do  forget_it <- readIORef v_Keep_tmp_files
95               unless forget_it $ do
96               verb <- readIORef v_Verbose
97               cleanTempFiles verb
98      ) $ do
99         -- exceptions will be blocked while we clean the temporary files,
100         -- so there shouldn't be any difficulty if we receive further
101         -- signals.
102
103         -- install signal handlers
104    main_thread <- myThreadId
105 #ifndef mingw32_TARGET_OS
106    let sig_handler = Catch (throwTo main_thread 
107                                 (DynException (toDyn Interrupted)))
108    installHandler sigQUIT sig_handler Nothing 
109    installHandler sigINT  sig_handler Nothing
110 #endif
111
112    pgm    <- getProgName
113    writeIORef v_Prog_name pgm
114
115    argv   <- getArgs
116
117         -- grab any -B options from the command line first
118    argv'  <- setTopDir argv
119    top_dir <- readIORef v_TopDir
120
121    let installed s = top_dir ++ '/':s
122        inplace s   = top_dir ++ '/':cCURRENT_DIR ++ '/':s
123
124        installed_pkgconfig = installed ("package.conf")
125        inplace_pkgconfig   = inplace (cGHC_DRIVER_DIR ++ "/package.conf.inplace")
126
127         -- discover whether we're running in a build tree or in an installation,
128         -- by looking for the package configuration file.
129    am_installed <- doesFileExist installed_pkgconfig
130
131    if am_installed
132         then writeIORef v_Path_package_config installed_pkgconfig
133         else do am_inplace <- doesFileExist inplace_pkgconfig
134                 if am_inplace
135                     then writeIORef v_Path_package_config inplace_pkgconfig
136                     else throwDyn (OtherError "can't find package.conf")
137
138         -- set the location of our various files
139    if am_installed
140         then do writeIORef v_Path_usage (installed "ghc-usage.txt")
141                 writeIORef v_Pgm_L (installed "unlit")
142                 writeIORef v_Pgm_m (installed "ghc-asm")
143                 writeIORef v_Pgm_s (installed "ghc-split")
144
145         else do writeIORef v_Path_usage (inplace (cGHC_DRIVER_DIR ++ "/ghc-usage.txt"))
146                 writeIORef v_Pgm_L (inplace cGHC_UNLIT)
147                 writeIORef v_Pgm_m (inplace cGHC_MANGLER)
148                 writeIORef v_Pgm_s (inplace cGHC_SPLIT)
149
150         -- read the package configuration
151    conf_file <- readIORef v_Path_package_config
152    contents <- readFile conf_file
153    let pkg_details = read contents      -- ToDo: faster
154    writeIORef v_Package_details pkg_details
155
156         -- find the phase to stop after (i.e. -E, -C, -c, -S flags)
157    (flags2, mode, stop_flag) <- getGhcMode argv'
158    writeIORef v_GhcMode mode
159
160         -- force lang to "C" if the -C flag was given
161    case mode of StopBefore HCc -> writeIORef v_Hsc_Lang HscC
162                 _ -> return ()
163
164         -- process all the other arguments, and get the source files
165    non_static <- processArgs static_flags flags2 []
166
167         -- find the build tag, and re-process the build-specific options
168    more_opts <- findBuildTag
169    way_non_static <- processArgs static_flags more_opts []
170
171         -- give the static flags to hsc
172    static_opts <- buildStaticHscOpts
173    writeIORef v_Static_hsc_opts static_opts
174
175         -- warnings
176    warn_level <- readIORef v_Warning_opt
177
178    let warn_opts =  case warn_level of
179                         W_default -> standardWarnings
180                         W_        -> minusWOpts
181                         W_all     -> minusWallOpts
182                         W_not     -> []
183
184         -- build the default DynFlags (these may be adjusted on a per
185         -- module basis by OPTIONS pragmas and settings in the interpreter).
186
187    core_todo <- buildCoreToDo
188    stg_todo  <- buildStgToDo
189
190    lang <- readIORef v_Hsc_Lang
191    writeIORef v_DynFlags 
192         DynFlags{ coreToDo = core_todo,
193                   stgToDo  = stg_todo,
194                   hscLang  = lang,
195                   -- leave out hscOutName for now
196                   flags = [] }
197
198         -- the rest of the arguments are "dynamic"
199    srcs <- processArgs dynamic_flags (way_non_static ++ 
200                                         non_static ++ warn_opts) []
201         -- save the "initial DynFlags" away
202    init_dyn_flags <- readIORef v_DynFlags
203    writeIORef v_InitDynFlags init_dyn_flags
204
205         -- complain about any unknown flags
206    mapM unknownFlagErr [ f | f@('-':_) <- srcs ]
207
208         -- get the -v flag
209    verb <- readIORef v_Verbose
210
211    when verb (do hPutStr stderr "Glasgow Haskell Compiler, Version "
212                  hPutStr stderr cProjectVersion
213                  hPutStr stderr ", for Haskell 98, compiled by GHC version "
214                  hPutStrLn stderr cBooterVersion)
215
216    when verb (hPutStrLn stderr ("Using package config file: " ++ conf_file))
217
218         -- initialise the finder
219    initFinder pkg_details
220
221         -- mkdependHS is special
222    when (mode == DoMkDependHS) beginMkDependHS
223
224         -- make/interactive require invoking the compilation manager
225    if (mode == DoMake)        then beginMake pkg_details srcs else do
226    if (mode == DoInteractive) then beginInteractive srcs      else do
227
228         -- for each source file, find which phases to run
229    pipelines <- mapM (genPipeline mode stop_flag True) srcs
230    let src_pipelines = zip srcs pipelines
231
232         -- sanity checking
233    o_file <- readIORef v_Output_file
234    ohi    <- readIORef v_Output_hi
235    if length srcs > 1 && (isJust ohi || (isJust o_file && mode /= DoLink))
236         then throwDyn (UsageError "can't apply -o or -ohi options to multiple source files")
237         else do
238
239    if null srcs then throwDyn (UsageError "no input files") else do
240
241         -- save the flag state, because this could be modified by OPTIONS 
242         -- pragmas during the compilation, and we'll need to restore it
243         -- before starting the next compilation.
244    saved_driver_state <- readIORef v_Driver_state
245
246    let compileFile (src, phases) = do
247           writeIORef v_Driver_state saved_driver_state
248           writeIORef v_DynFlags init_dyn_flags
249           r <- runPipeline phases src (mode==DoLink) True
250           return r
251
252    o_files <- mapM compileFile src_pipelines
253
254    when (mode == DoMkDependHS) endMkDependHS
255    when (mode == DoLink) (doLink o_files)
256
257         -- grab the last -B option on the command line, and
258         -- set topDir to its value.
259 setTopDir :: [String] -> IO [String]
260 setTopDir args = do
261   let (minusbs, others) = partition (prefixMatch "-B") args
262   (case minusbs of
263     []   -> writeIORef v_TopDir clibdir
264     some -> writeIORef v_TopDir (drop 2 (last some)))
265   return others
266
267 beginMake :: PackageConfigInfo -> [String] -> IO ()
268 beginMake pkg_details mods
269    | null mods
270    = throwDyn (UsageError "no input files")
271    | not (null (tail mods))
272    = throwDyn (UsageError "only one module allowed with --make")
273    | otherwise
274    = do state <- cmInit pkg_details
275         cmLoadModule state (mkModuleName (head mods))
276         return ()
277
278 beginInteractive srcs = panic "`ghc --interactive' unimplemented"