{-# OPTIONS -fno-warn-incomplete-patterns #-}
-----------------------------------------------------------------------------
--- $Id: Main.hs,v 1.50 2001/02/12 13:33:46 simonmar Exp $
+-- $Id: Main.hs,v 1.67 2001/05/31 11:32:25 simonmar Exp $
--
-- GHC Driver program
--
#endif
import CompManager
+import ParsePkgConf
import DriverPipeline
import DriverState
import DriverFlags
import DriverMkDepend
import DriverUtil
import Panic
-import DriverPhases ( Phase(..), haskellish_file )
+import DriverPhases ( Phase(..), haskellish_src_file, objish_file )
import CmdLineOpts
import TmpFiles
import Finder ( initFinder )
import CmStaticInfo
import Config
+import Outputable
import Util
-
import Concurrent
import Directory
import IOExts
-----------------------------------------------------------------------------
-- ToDo:
--- -nohi doesn't work
-- new mkdependHS doesn't support all the options that the old one did (-X et al.)
-- time commands when run with -v
-- split marker
--- mkDLL
-- java generation
-- user ways
-- Win32 support: proper signal handling
else do am_inplace <- doesFileExist inplace_pkgconfig
if am_inplace
then writeIORef v_Path_package_config inplace_pkgconfig
- else throwDyn (OtherError "can't find package.conf")
+ else throwDyn (InstallationError
+ ("Can't find package.conf in " ++
+ inplace_pkgconfig))
-- set the location of our various files
if am_installed
writeIORef v_Pgm_L (installed "unlit")
writeIORef v_Pgm_m (installed "ghc-asm")
writeIORef v_Pgm_s (installed "ghc-split")
+#if defined(mingw32_TARGET_OS) && defined(MINIMAL_UNIX_DEPS)
+ writeIORef v_Pgm_T (installed cTOUCH)
+#endif
else do writeIORef v_Path_usage (inplace (cGHC_DRIVER_DIR ++ "/ghc-usage.txt"))
writeIORef v_Pgm_L (inplace cGHC_UNLIT)
writeIORef v_Pgm_m (inplace cGHC_MANGLER)
writeIORef v_Pgm_s (inplace cGHC_SPLIT)
+#if defined(mingw32_TARGET_OS) && defined(MINIMAL_UNIX_DEPS)
+ writeIORef v_Pgm_T (inplace cTOUCH)
+#endif
-- read the package configuration
conf_file <- readIORef v_Path_package_config
- contents <- readFile conf_file
- let pkg_details = read contents -- ToDo: faster
+ r <- parsePkgConf conf_file
+ case r of {
+ Left err -> throwDyn (InstallationError (showSDoc err));
+ Right pkg_details -> do
+
writeIORef v_Package_details pkg_details
-- find the phase to stop after (i.e. -E, -C, -c, -S flags)
(flags2, mode, stop_flag) <- getGhcMode argv'
writeIORef v_GhcMode mode
+ -- Show the GHCi banner?
+# ifdef GHCI
+ when (mode == DoInteractive) $
+ hPutStrLn stdout ghciWelcomeMsg
+# endif
+
-- process all the other arguments, and get the source files
non_static <- processArgs static_flags flags2 []
+ -- -O and --interactive are not a good combination
+ -- ditto with any kind of way selection
+ orig_opt_level <- readIORef v_OptLevel
+ when (orig_opt_level > 0 && mode == DoInteractive) $
+ do putStr "warning: -O conflicts with --interactive; -O turned off.\n"
+ writeIORef v_OptLevel 0
+ orig_ways <- readIORef v_Ways
+ when (not (null orig_ways) && mode == DoInteractive) $
+ do throwDyn (UsageError
+ "--interactive can't be used with -prof, -ticky, -unreg or -smp.")
+
-- Find the build tag, and re-process the build-specific options.
-- Also add in flags for unregisterised compilation, if
-- GhcUnregisterised=YES.
static_opts <- buildStaticHscOpts
writeIORef v_Static_hsc_opts static_opts
- -- warnings
- warn_level <- readIORef v_Warning_opt
-
- let warn_opts = case warn_level of
- W_default -> standardWarnings
- W_ -> minusWOpts
- W_all -> minusWallOpts
- W_not -> []
-
- -- build the default DynFlags (these may be adjusted on a per
- -- module basis by OPTIONS pragmas and settings in the interpreter).
+ -- build the default DynFlags (these may be adjusted on a per
+ -- module basis by OPTIONS pragmas and settings in the interpreter).
core_todo <- buildCoreToDo
stg_todo <- buildStgToDo
-- by module basis, using only the -fvia-C and -fasm flags. If the global
-- HscLang is not HscC or HscAsm, -fvia-C and -fasm have no effect.
opt_level <- readIORef v_OptLevel
+
+
let lang = case mode of
StopBefore HCc -> HscC
DoInteractive -> HscInterpreted
}
-- the rest of the arguments are "dynamic"
- srcs <- processArgs dynamic_flags (way_non_static ++
- non_static ++ warn_opts) []
+ srcs <- processArgs dynamic_flags (way_non_static ++ non_static) []
-- save the "initial DynFlags" away
init_dyn_flags <- readIORef v_DynFlags
writeIORef v_InitDynFlags init_dyn_flags
-- mkdependHS is special
when (mode == DoMkDependHS) beginMkDependHS
+ -- -ohi sanity checking
+ ohi <- readIORef v_Output_hi
+ if (isJust ohi &&
+ (mode == DoMake || mode == DoInteractive || length srcs > 1))
+ then throwDyn (UsageError "-ohi can only be used when compiling a single source file")
+ else do
+
-- make/interactive require invoking the compilation manager
if (mode == DoMake) then beginMake srcs else do
if (mode == DoInteractive) then beginInteractive srcs else do
- -- sanity checking
+ -- -o sanity checking
o_file <- readIORef v_Output_file
- ohi <- readIORef v_Output_hi
- if length srcs > 1 && (isJust ohi || (isJust o_file && mode /= DoLink && mode /= DoMkDLL))
- then throwDyn (UsageError "can't apply -o or -ohi options to multiple source files")
+ if (length srcs > 1 && isJust o_file && mode /= DoLink && mode /= DoMkDLL)
+ then throwDyn (UsageError "can't apply -o to multiple source files")
else do
if null srcs then throwDyn (UsageError "no input files") else do
let compileFile src = do
writeIORef v_DynFlags init_dyn_flags
+ exists <- doesFileExist src
+ when (not exists) $
+ throwDyn (CmdLineError ("file `" ++ src ++ "' does not exist"))
+
-- We compile in two stages, because the file may have an
-- OPTIONS pragma that affects the compilation pipeline (eg. -fvia-C)
-
let (basename, suffix) = splitFilename src
- -- just preprocess
- pp <- if not (haskellish_file src) || mode == StopBefore Hsc
+ -- just preprocess (Haskell source only)
+ pp <- if not (haskellish_src_file src) || mode == StopBefore Hsc
then return src else do
phases <- genPipeline (StopBefore Hsc) stop_flag
False{-not persistent-} defaultHscLang src
when (mode == DoMkDependHS) endMkDependHS
when (mode == DoLink) (doLink o_files)
when (mode == DoMkDLL) (doMkDLL o_files)
-
+ }
-- grab the last -B option on the command line, and
-- set topDir to its value.
setTopDir :: [String] -> IO [String]
setTopDir args = do
let (minusbs, others) = partition (prefixMatch "-B") args
(case minusbs of
- [] -> writeIORef v_TopDir clibdir
+ [] -> throwDyn (InstallationError ("missing -B<dir> option"))
some -> writeIORef v_TopDir (drop 2 (last some)))
return others
beginMake :: [String] -> IO ()
-beginMake mods
- = do case mods of
+beginMake fileish_args
+ = do let (objs, mods) = partition objish_file fileish_args
+ mapM (add v_Ld_inputs) objs
+
+ case mods of
[] -> throwDyn (UsageError "no input files")
[mod] -> do state <- cmInit Batch
cmLoadModule state mod
beginInteractive :: [String] -> IO ()
#ifndef GHCI
-beginInteractive = throwDyn (OtherError "not built for interactive use")
+beginInteractive = throwDyn (CmdLineError "not built for interactive use")
#else
-beginInteractive mods
- = do state <- cmInit Interactive
- let mod = case mods of
- [] -> Nothing
- [mod] -> Just mod
- _ -> throwDyn (UsageError
- "only one module allowed with --interactive")
- interactiveUI state mod
+beginInteractive fileish_args
+ = do minus_ls <- readIORef v_Cmdline_libraries
+
+ let (objs, mods) = partition objish_file fileish_args
+ libs = map Left objs ++ map Right minus_ls
+
+ state <- cmInit Interactive
+ case mods of
+ [] -> interactiveUI state Nothing libs
+ [mod] -> interactiveUI state (Just mod) libs
+ _ -> throwDyn (UsageError
+ "only one module allowed with --interactive")
#endif