[project @ 2001-12-10 01:27:59 by sebc]
[ghc-hetmet.git] / ghc / compiler / main / DriverFlags.hs
index ce02488..e4dd662 100644 (file)
@@ -1,7 +1,7 @@
 {-# OPTIONS -#include "hschooks.h" #-}
 
 -----------------------------------------------------------------------------
--- $Id: DriverFlags.hs,v 1.52 2001/03/29 18:40:09 rrt Exp $
+-- $Id: DriverFlags.hs,v 1.81 2001/12/10 01:28:00 sebc Exp $
 --
 -- Driver flags
 --
 
 module DriverFlags ( 
        processArgs, OptKind(..), static_flags, dynamic_flags, 
-       v_InitDynFlags, v_DynFlags, getDynFlags, dynFlag, 
+       getDynFlags, dynFlag, 
        getOpts, getVerbFlag, addCmdlineHCInclude,
        buildStaticHscOpts, 
-       runSomething,
        machdepCCOpts
   ) where
 
 #include "HsVersions.h"
+#include "../includes/config.h"
 
 import DriverState
 import DriverUtil
-import TmpFiles        ( v_TmpDir, kludgedSystem )
+import SysTools
 import CmdLineOpts
 import Config
 import Util
@@ -30,11 +30,11 @@ import Panic
 
 import Exception
 import IOExts
+import System          ( exitWith, ExitCode(..) )
 
 import IO
 import Maybe
 import Monad
-import System
 import Char
 
 -----------------------------------------------------------------------------
@@ -71,15 +71,15 @@ data OptKind
        | AnySuffixPred (String -> Bool) (String -> IO ())
 
 processArgs :: [(String,OptKind)] -> [String] -> [String]
-   -> IO [String]  -- returns spare args
+           -> IO [String]  -- returns spare args
 processArgs _spec [] spare = return (reverse spare)
+
 processArgs spec args@(('-':arg):args') spare = do
   case findArg spec arg of
-    Just (rest,action) -> 
-      do args' <- processOneArg action rest args
-        processArgs spec args' spare
-    Nothing -> 
-      processArgs spec args' (('-':arg):spare)
+    Just (rest,action) -> do args' <- processOneArg action rest args
+                            processArgs spec args' spare
+    Nothing           -> processArgs spec args' (('-':arg):spare)
+
 processArgs spec (arg:args) spare = 
   processArgs spec args (arg:spare)
 
@@ -127,7 +127,8 @@ processOneArg action rest (dash_arg@('-':arg):args) =
 findArg :: [(String,OptKind)] -> String -> Maybe (String,OptKind)
 findArg spec arg
   = case [ (remove_spaces rest, k) 
-        | (pat,k) <- spec, Just rest <- [my_prefix_match pat arg],
+        | (pat,k)   <- spec, 
+          Just rest <- [my_prefix_match pat arg],
           arg_ok k rest arg ] 
     of
        []      -> Nothing
@@ -151,20 +152,23 @@ arg_ok (AnySuffixPred p _)  rest arg = p arg
 -- flags further down the list with the same prefix.
 
 static_flags = 
-  [  ------- help -------------------------------------------------------
-     ( "?"             , NoArg long_usage)
-  ,  ( "-help"         , NoArg long_usage)
-  
-
-      ------- version ----------------------------------------------------
-  ,  ( "-version"       , NoArg (do hPutStrLn stdout (cProjectName
+  [  ------- help / version ----------------------------------------------
+     ( "?"              , NoArg showGhcUsage)
+  ,  ( "-help"          , NoArg showGhcUsage)
+  ,  ( "-print-libdir"   , NoArg (do getTopDir >>= putStrLn
+                                    exitWith ExitSuccess))  
+  ,  ( "-version"       , NoArg (do putStrLn (cProjectName
                                      ++ ", version " ++ cProjectVersion)
                                     exitWith ExitSuccess))
-  ,  ( "-numeric-version", NoArg (do hPutStrLn stdout cProjectVersion
+  ,  ( "-numeric-version", NoArg (do putStrLn cProjectVersion
                                     exitWith ExitSuccess))
 
       ------- verbosity ----------------------------------------------------
-  ,  ( "n"              , NoArg (writeIORef v_Dry_run True) )
+  ,  ( "n"              , NoArg setDryRun )
+
+       ------- GHCi -------------------------------------------------------
+  ,  ( "ignore-dot-ghci", NoArg (writeIORef v_Read_DotGHCi False) )
+  ,  ( "read-dot-ghci"  , NoArg (writeIORef v_Read_DotGHCi True) )
 
        ------- recompilation checker --------------------------------------
   ,  ( "recomp"                , NoArg (writeIORef v_Recomp True) )
@@ -206,16 +210,21 @@ static_flags =
   ,  ( "odir"          , HasArg (writeIORef v_Output_dir  . Just) )
   ,  ( "o"             , SepArg (writeIORef v_Output_file . Just) )
   ,  ( "osuf"          , HasArg (writeIORef v_Object_suf  . Just) )
+  ,  ( "hcsuf"         , HasArg (writeIORef v_HC_suf      . Just) )
   ,  ( "hisuf"         , HasArg (writeIORef v_Hi_suf) )
-  ,  ( "tmpdir"                , HasArg (writeIORef v_TmpDir . (++ "/")) )
-  ,  ( "ohi"           , HasArg (\s -> case s of 
-                                         "-" -> writeIORef v_Hi_on_stdout True
-                                         _   -> writeIORef v_Output_hi (Just s)) )
+  ,  ( "hidir"         , HasArg (writeIORef v_Hi_dir . Just) )
+  ,  ( "buildtag"      , HasArg (writeIORef v_Build_tag) )
+  ,  ( "tmpdir"                , HasArg setTmpDir)
+  ,  ( "ohi"           , HasArg (writeIORef v_Output_hi   . Just) )
        -- -odump?
 
   ,  ( "keep-hc-file"   , AnySuffix (\_ -> writeIORef v_Keep_hc_files True) )
   ,  ( "keep-s-file"    , AnySuffix (\_ -> writeIORef v_Keep_s_files  True) )
   ,  ( "keep-raw-s-file", AnySuffix (\_ -> writeIORef v_Keep_raw_s_files  True) )
+#ifdef ILX
+  ,  ( "keep-il-file"   , AnySuffix (\_ -> writeIORef v_Keep_il_files True) )
+  ,  ( "keep-ilx-file"  , AnySuffix (\_ -> writeIORef v_Keep_ilx_files True) )
+#endif
   ,  ( "keep-tmp-files" , AnySuffix (\_ -> writeIORef v_Keep_tmp_files True) )
 
   ,  ( "split-objs"    , NoArg (if can_split
@@ -237,17 +246,12 @@ static_flags =
         ------- Packages ----------------------------------------------------
   ,  ( "package-name"   , HasArg (\s -> add v_Opt_C ("-inpackage="++s)) )
 
+  ,  ( "package-conf"   , HasArg (readPackageConf) )
   ,  ( "package"        , HasArg (addPackage) )
   ,  ( "syslib"         , HasArg (addPackage) )        -- for compatibility w/ old vsns
 
         ------- Specific phases  --------------------------------------------
-  ,  ( "pgmL"           , HasArg (writeIORef v_Pgm_L) )
-  ,  ( "pgmP"           , HasArg (writeIORef v_Pgm_P) )
-  ,  ( "pgmc"           , HasArg (writeIORef v_Pgm_c) )
-  ,  ( "pgmm"           , HasArg (writeIORef v_Pgm_m) )
-  ,  ( "pgms"           , HasArg (writeIORef v_Pgm_s) )
-  ,  ( "pgma"           , HasArg (writeIORef v_Pgm_a) )
-  ,  ( "pgml"           , HasArg (writeIORef v_Pgm_l) )
+  ,  ( "pgm"           , HasArg setPgm )
 
   ,  ( "optdep"                , HasArg (add v_Opt_dep) )
   ,  ( "optl"          , HasArg (add v_Opt_l) )
@@ -271,6 +275,9 @@ static_flags =
   ,  ( "fmax-simplifier-iterations", 
                Prefix (writeIORef v_MaxSimplifierIterations . read) )
 
+  ,  ( "frule-check", 
+               SepArg (\s -> writeIORef v_RuleCheck (Just s)) )
+
   ,  ( "fusagesp"         , NoArg (do writeIORef v_UsageSPInf True
                                       add v_Opt_C "-fusagesp-on") )
 
@@ -292,88 +299,39 @@ static_flags =
   ,  ( "f",                    AnySuffixPred (isStaticHscFlag) (add v_Opt_C) )
   ]
 
------------------------------------------------------------------------------
--- parse the dynamic arguments
-
--- v_InitDynFlags 
---     is the "baseline" dynamic flags, initialised from
---     the defaults and command line options, and updated by the
---     ':s' command in GHCi.
---
--- v_DynFlags
---     is the dynamic flags for the current compilation.  It is reset
---     to the value of v_InitDynFlags before each compilation, then
---     updated by reading any OPTIONS pragma in the current module.
-
-GLOBAL_VAR(v_InitDynFlags, defaultDynFlags, DynFlags)
-GLOBAL_VAR(v_DynFlags,     defaultDynFlags, DynFlags)
-
-updDynFlags f = do
-   dfs <- readIORef v_DynFlags
-   writeIORef v_DynFlags (f dfs)
-
-getDynFlags :: IO DynFlags
-getDynFlags = readIORef v_DynFlags
-
-dynFlag :: (DynFlags -> a) -> IO a
-dynFlag f = do dflags <- readIORef v_DynFlags; return (f dflags)
-
-setDynFlag f   = updDynFlags (\dfs -> dopt_set dfs f)
-unSetDynFlag f = updDynFlags (\dfs -> dopt_unset dfs f)
-
-addOpt_L     a = updDynFlags (\s -> s{opt_L =  a : opt_L s})
-addOpt_P     a = updDynFlags (\s -> s{opt_P =  a : opt_P s})
-addOpt_c     a = updDynFlags (\s -> s{opt_c =  a : opt_c s})
-addOpt_a     a = updDynFlags (\s -> s{opt_a =  a : opt_a s})
-addOpt_m     a = updDynFlags (\s -> s{opt_m =  a : opt_m s})
-
-addCmdlineHCInclude a = 
-   updDynFlags (\s -> s{cmdlineHcIncludes =  a : cmdlineHcIncludes s})
-
-       -- we add to the options from the front, so we need to reverse the list
-getOpts :: (DynFlags -> [a]) -> IO [a]
-getOpts opts = dynFlag opts >>= return . reverse
-
--- we can only change HscC to HscAsm and vice-versa with dynamic flags 
--- (-fvia-C and -fasm).
--- NB: we can also set the new lang to ILX, via -filx.  I hope this is right
-setLang l = do
-   dfs <- readIORef v_DynFlags
-   case hscLang dfs of
-       HscC   -> writeIORef v_DynFlags dfs{ hscLang = l }
-       HscAsm -> writeIORef v_DynFlags dfs{ hscLang = l }
-       _      -> return ()
-
-setVerbosityAtLeast n =
-  updDynFlags (\dfs -> if verbosity dfs < n 
-                         then dfs{ verbosity = n }
-                         else dfs)
-
-setVerbosity "" = updDynFlags (\dfs -> dfs{ verbosity = 3 })
-setVerbosity n 
-  | all isDigit n = updDynFlags (\dfs -> dfs{ verbosity = read n })
-  | otherwise     = throwDyn (UsageError "can't parse verbosity flag (-v<n>)")
-
-getVerbFlag = do
-   verb <- dynFlag verbosity
-   if verb >= 3  then return  "-v" else return ""
-
 dynamic_flags = [
 
      ( "cpp",          NoArg  (updDynFlags (\s -> s{ cppFlag = True })) )
+  ,  ( "F",             NoArg  (updDynFlags (\s -> s{ ppFlag = True })) )
   ,  ( "#include",     HasArg (addCmdlineHCInclude) )
 
   ,  ( "v",            OptPrefix (setVerbosity) )
 
   ,  ( "optL",         HasArg (addOpt_L) )
   ,  ( "optP",         HasArg (addOpt_P) )
+  ,  ( "optF",          HasArg (addOpt_F) )
   ,  ( "optc",         HasArg (addOpt_c) )
   ,  ( "optm",         HasArg (addOpt_m) )
   ,  ( "opta",         HasArg (addOpt_a) )
+#ifdef ILX
+  ,  ( "optI",         HasArg (addOpt_I) )
+  ,  ( "opti",         HasArg (addOpt_i) )
+#endif
 
        ------ HsCpp opts ---------------------------------------------------
+       -- With a C compiler whose system() doesn't use a UNIX shell (i.e.
+       -- mingwin gcc), -D and -U args must *not* be quoted, as the quotes
+       -- will be interpreted as part of the arguments, and not stripped;
+       -- on all other systems, quoting is necessary, to avoid interpretation
+       -- of shell metacharacters in the arguments (e.g. green-card's
+       -- -DBEGIN_GHC_ONLY='}-' trick).
+#ifndef mingw32_TARGET_OS
   ,  ( "D",            Prefix (\s -> addOpt_P ("-D'"++s++"'") ) )
   ,  ( "U",            Prefix (\s -> addOpt_P ("-U'"++s++"'") ) )
+#else
+  ,  ( "D",            Prefix (\s -> addOpt_P ("-D"++s) ) )
+  ,  ( "U",            Prefix (\s -> addOpt_P ("-U"++s) ) )
+#endif
 
        ------ Debugging ----------------------------------------------------
   ,  ( "dstg-stats",   NoArg (writeIORef v_StgStats True) )
@@ -393,7 +351,7 @@ dynamic_flags = [
   ,  ( "ddump-simpl",           NoArg (setDynFlag Opt_D_dump_simpl) )
   ,  ( "ddump-simpl-iterations", NoArg (setDynFlag Opt_D_dump_simpl_iterations) )
   ,  ( "ddump-spec",            NoArg (setDynFlag Opt_D_dump_spec) )
-  ,  ( "ddump-sat",             NoArg (setDynFlag Opt_D_dump_sat) )
+  ,  ( "ddump-prep",            NoArg (setDynFlag Opt_D_dump_prep) )
   ,  ( "ddump-stg",             NoArg (setDynFlag Opt_D_dump_stg) )
   ,  ( "ddump-stranal",         NoArg (setDynFlag Opt_D_dump_stranal) )
   ,  ( "ddump-tc",              NoArg (setDynFlag Opt_D_dump_tc) )
@@ -436,9 +394,8 @@ dynamic_flags = [
   ,  ( "fasm",         AnySuffix (\_ -> setLang HscAsm) )
   ,  ( "fvia-c",       NoArg (setLang HscC) )
   ,  ( "fvia-C",       NoArg (setLang HscC) )
-#ifdef ILX
   ,  ( "filx",         NoArg (setLang HscILX) )
-#endif
+  ,  ( "fno-code",      NoArg (setLang HscNothing) )
 
        -- "active negatives"
   ,  ( "fno-implicit-prelude",  NoArg (setDynFlag Opt_NoImplicitPrelude) )
@@ -488,8 +445,6 @@ decodeSize str
         n      = read m  :: Double
        pred c = isDigit c || c == '.'
 
-floatOpt :: IORef Double -> String -> IO ()
-floatOpt ref str = writeIORef ref (read str :: Double)
 
 -----------------------------------------------------------------------------
 -- RTS Hooks
@@ -512,7 +467,8 @@ buildStaticHscOpts = do
            0 -> hsc_minusNoO_flags
            1 -> hsc_minusO_flags
            2 -> hsc_minusO2_flags
-           _ -> error "unknown opt level"
+           n -> throwDyn (CmdLineError ("unknown optimisation level: "
+                                         ++ show n))
            -- ToDo: -Ofile
  
        -- take into account -fno-* flags by removing the equivalent -f*
@@ -527,30 +483,6 @@ buildStaticHscOpts = do
   return ( static : filtered_opts )
 
 -----------------------------------------------------------------------------
--- Running an external program
-
--- sigh, here because both DriverMkDepend & DriverPipeline need it.
-
-runSomething phase_name cmd
- = do
-   verb <- dynFlag verbosity
-   when (verb >= 2) $ hPutStrLn stderr ("*** " ++ phase_name)
-   when (verb >= 3) $ hPutStrLn stderr cmd
-   hFlush stderr
-
-   -- test for -n flag
-   n <- readIORef v_Dry_run
-   unless n $ do 
-
-   -- and run it!
-   exit_code <- kludgedSystem cmd phase_name
-
-   if exit_code /= ExitSuccess
-       then throwDyn (PhaseFailed phase_name exit_code)
-       else do when (verb >= 3) (hPutStr stderr "\n")
-               return ()
-
------------------------------------------------------------------------------
 -- Via-C compilation stuff
 
 -- flags returned are: ( all C compilations
@@ -559,7 +491,10 @@ runSomething phase_name cmd
 
 machdepCCOpts 
    | prefixMatch "alpha"   cTARGETPLATFORM  
-       = return ( ["-static"], [] )
+       = return ( ["-static", "-w", "-mieee"], [] )
+       -- For now, to suppress the gcc warning "call-clobbered
+       -- register used for global register variable", we simply
+       -- disable all warnings altogether using the -w flag. Oh well.
 
    | prefixMatch "hppa"    cTARGETPLATFORM  
         -- ___HPUX_SOURCE, not _HPUX_SOURCE, is #defined if -ansi!
@@ -586,16 +521,61 @@ machdepCCOpts
        = do n_regs <- dynFlag stolen_x86_regs
             sta    <- readIORef v_Static
             return ( [ if sta then "-DDONT_WANT_WIN32_DLL_SUPPORT" else "",
-                        if suffixMatch "mingw32" cTARGETPLATFORM then "-mno-cygwin -mwin32" else "" ],
+                        if suffixMatch "mingw32" cTARGETPLATFORM then "-mno-cygwin" else "" ],
                      [ "-fno-defer-pop", "-fomit-frame-pointer",
                        "-DSTOLEN_X86_REGS="++show n_regs ]
                    )
 
    | prefixMatch "mips"    cTARGETPLATFORM
-       = return ( ["static"], [] )
+       = return ( ["-static"], [] )
+
+   | prefixMatch "sparc"    cTARGETPLATFORM
+       = return ( [], ["-w"] )
+       -- For now, to suppress the gcc warning "call-clobbered
+       -- register used for global register variable", we simply
+       -- disable all warnings altogether using the -w flag. Oh well.
+
+   | prefixMatch "powerpc-apple-darwin" cTARGETPLATFORM
+       = return ( ["-no-cpp-precomp"], [""] )
 
    | prefixMatch "powerpc" cTARGETPLATFORM || prefixMatch "rs6000" cTARGETPLATFORM
-       = return ( ["static"], ["-finhibit-size-directive"] )
+       = return ( ["-static"], ["-finhibit-size-directive"] )
 
    | otherwise
        = return ( [], [] )
+
+
+
+addOpt_L a = updDynFlags (\s -> s{opt_L = a : opt_L s})
+addOpt_P a = updDynFlags (\s -> s{opt_P = a : opt_P s})
+addOpt_F a = updDynFlags (\s -> s{opt_F = a : opt_F s})
+addOpt_c a = updDynFlags (\s -> s{opt_c = a : opt_c s})
+addOpt_a a = updDynFlags (\s -> s{opt_a = a : opt_a s})
+addOpt_m a = updDynFlags (\s -> s{opt_m = a : opt_m s})
+#ifdef ILX
+addOpt_I a = updDynFlags (\s -> s{opt_I = a : opt_I s})
+addOpt_i a = updDynFlags (\s -> s{opt_i = a : opt_i s})
+#endif
+
+addCmdlineHCInclude a = updDynFlags (\s -> s{cmdlineHcIncludes =  a : cmdlineHcIncludes s})
+
+getOpts :: (DynFlags -> [a]) -> IO [a]
+       -- We add to the options from the front, so we need to reverse the list
+getOpts opts = dynFlag opts >>= return . reverse
+
+-- we can only change HscC to HscAsm and vice-versa with dynamic flags 
+-- (-fvia-C and -fasm). We can also set the new lang to ILX, via -filx.
+setLang l = updDynFlags (\ dfs -> case hscLang dfs of
+                                       HscC   -> dfs{ hscLang = l }
+                                       HscAsm -> dfs{ hscLang = l }
+                                       HscILX -> dfs{ hscLang = l }
+                                       _      -> dfs)
+
+setVerbosity "" = updDynFlags (\dfs -> dfs{ verbosity = 3 })
+setVerbosity n 
+  | all isDigit n = updDynFlags (\dfs -> dfs{ verbosity = read n })
+  | otherwise     = throwDyn (UsageError "can't parse verbosity flag (-v<n>)")
+
+getVerbFlag = do
+   verb <- dynFlag verbosity
+   if verb >= 3  then return  "-v" else return ""