--make is now the default (#3515), and -fno-code works with --make (#3783)
authorSimon Marlow <marlowsd@gmail.com>
Tue, 27 Apr 2010 12:28:51 +0000 (12:28 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Tue, 27 Apr 2010 12:28:51 +0000 (12:28 +0000)
If the command line contains any Haskell source files, then we behave
as if --make had been given.

The meaning of the -c flag has changed (back): -c now selects one-shot
compilation, but stops before linking.  However, to retain backwards
compatibility, -c is still allowed with --make, and means the same as
--make -no-link.  The -no-link flag has been un-deprecated.

-fno-code is now allowed with --make (#3783); the fact that it was
disabled before was largely accidental, it seems.  We also had some
regressions in this area: it seems that -fno-code was causing a .hc
file to be emitted in certain cases.  I've tidied up the code, there
was no need for -fno-code to be a "mode" flag, as far as I can tell.

-fno-code does not emit interface files, nor does it do recompilation
checking, as suggested in #3783.  This would make Haddock emit
interface files, for example, and I'm fairly sure we don't want to do
that.  Compiling with -fno-code is pretty quick anyway, perhaps we can
get away without recompilation checking.

compiler/main/DriverPipeline.hs
compiler/main/DynFlags.hs
compiler/main/HscMain.lhs
docs/users_guide/using.xml
ghc/Main.hs

index d54bb0f..387d5a1 100644 (file)
@@ -826,6 +826,7 @@ runPhase (Hsc src_flavour) stop hsc_env basename suff input_fn get_output_fn _ma
        src_timestamp <- liftIO $ getModificationTime (basename <.> suff)
 
        let force_recomp = dopt Opt_ForceRecomp dflags
+           hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
        source_unchanged <-
           if force_recomp || not (isStopLn stop)
                -- Set source_unchanged to False unconditionally if
@@ -842,7 +843,6 @@ runPhase (Hsc src_flavour) stop hsc_env basename suff input_fn get_output_fn _ma
                                  else return False
 
   -- get the DynFlags
-       let hsc_lang = hscMaybeAdjustTarget dflags stop src_flavour (hscTarget dflags)
        let next_phase = hscNextPhase dflags src_flavour hsc_lang
        output_fn  <- liftIO $ get_output_fn dflags next_phase (Just location4)
 
index 8a8b052..5705bb3 100644 (file)
@@ -1063,10 +1063,8 @@ dynamic_flags = [
          (Deprecated "Use -exclude-module instead")
 
         -------- Linking ----------------------------------------------------
-  , Flag "c"              (NoArg (upd $ \d -> d{ ghcLink=NoLink } ))
-         Supported
   , Flag "no-link"        (NoArg (upd $ \d -> d{ ghcLink=NoLink } ))
-         (Deprecated "Use -c instead")
+         Supported
   , Flag "shared"         (NoArg (upd $ \d -> d{ ghcLink=LinkDynLib } ))
          Supported
   , Flag "dynload"        (HasArg (upd . parseDynLibLoaderMode))
@@ -1387,7 +1385,9 @@ dynamic_flags = [
   , Flag "fvia-c"           (NoArg (setObjTarget HscC)) Supported
   , Flag "fvia-C"           (NoArg (setObjTarget HscC)) Supported
 
-  , Flag "fno-code"         (NoArg (setTarget HscNothing)) Supported
+  , Flag "fno-code"         (NoArg (do upd $ \d -> d{ ghcLink=NoLink }
+                                       setTarget HscNothing))
+                                   Supported
   , Flag "fbyte-code"       (NoArg (setTarget HscInterpreted)) Supported
   , Flag "fobject-code"     (NoArg (setTarget defaultHscTarget)) Supported
 
index 5590744..b183250 100644 (file)
@@ -435,7 +435,12 @@ hscOneShotCompiler =
 
   , hscRecompile = genericHscRecompile hscOneShotCompiler
 
-  , hscBackend = genericHscBackend hscOneShotCompiler
+  , hscBackend = \ tc_result mod_summary mb_old_hash -> do
+       hsc_env <- getSession
+       case hscTarget (hsc_dflags hsc_env) of
+         HscNothing -> return (HscRecomp False ())
+         _otherw    -> genericHscBackend hscOneShotCompiler 
+                                         tc_result mod_summary mb_old_hash
 
   , hscGenBootOutput = \tc_result mod_summary mb_old_iface -> do
        (iface, changed, _) <- hscSimpleIface tc_result mb_old_iface
@@ -536,13 +541,7 @@ hscNothingCompiler =
        details <- genModDetails iface
        return (HscNoRecomp, iface, details)
 
-  , hscRecompile = \mod_summary mb_old_hash ->
-      case ms_hsc_src mod_summary of
-        ExtCoreFile ->
-          panic "hscCompileNothing: cannot do external core"
-        _otherwise -> do
-          tc_result <- hscFileFrontEnd mod_summary
-          hscBackend hscNothingCompiler tc_result mod_summary mb_old_hash
+  , hscRecompile = genericHscRecompile hscNothingCompiler
 
   , hscBackend = \tc_result _mod_summary mb_old_iface -> do
        (iface, _changed, details) <- hscSimpleIface tc_result mb_old_iface
index 6ffdf2a..95f5b94 100644 (file)
@@ -6,6 +6,77 @@
   <indexterm><primary>using GHC</primary></indexterm>
 
   <sect1>
+    <title>Getting started: compiling programs</title>
+
+    <para>
+      In this chapter you'll find a complete reference to the GHC
+      command-line syntax, including all 400+ flags.  It's a large and
+      complex system, and there are lots of details, so it can be
+      quite hard to figure out how to get started.  With that in mind,
+      this introductory section provides a quick introduction to the
+      basic usage of GHC for compiling a Haskell program, before the
+      following sections dive into the full syntax.
+    </para>
+
+    <para>
+      Let's create a Hello World program, and compile and run it.
+      First, create a file <filename>hello.hs</filename> containing
+      the Haskell code:
+    </para>
+
+<programlisting>
+main = putStrLn "Hello, World!"
+</programlisting>
+
+    <para>To compile the program, use GHC like this:</para>
+
+<screen>
+$ ghc hello.hs</screen>
+
+     <para>(where <literal>$</literal> represents the prompt: don't
+       type it).  GHC will compile the source
+       file <filename>hello.hs</filename>, producing
+       an <firstterm>object
+       file</firstterm> <filename>hello.o</filename> and
+       an <firstterm>interface
+       file</firstterm> <filename>hello.hi</filename>, and then it
+       will link the object file to the libraries that come with GHC
+       to produce an executable called <filename>hello</filename> on
+       Unix/Linux/Mac, or <filename>hello.exe</filename> on
+       Windows.</para>
+
+    <para>
+      By default GHC will be very quiet about what it is doing, only
+      printing error messages.  If you want to see in more detail
+      what's going on behind the scenes, add <option>-v</option> to
+      the command line.
+    </para>
+
+    <para>
+      Then we can run the program like this:
+    </para>
+
+<screen>
+$ ./hello
+Hello World!</screen>
+
+    <para>
+      If your program contains multiple modules, then you only need to
+      tell GHC the name of the source file containing
+      the <filename>Main</filename> module, and GHC will examine
+      the <literal>import</literal> declarations to find the other
+      modules that make up the program and find their source files.
+      This means that, with the exception of
+      the <literal>Main</literal> module, every source file should be
+      named after the module name that it contains (with dots replaced
+      by directory separators).  For example, the
+      module <literal>Data.Person</literal> would be in the
+      file <filename>Data/Person.hs</filename> on Unix/Linux/Mac,
+      or <filename>Data\Person.hs</filename> on Windows.
+    </para>
+  </sect1>
+
+  <sect1>
     <title>Options overview</title>
     
     <para>GHC's behaviour is controlled by
@@ -110,7 +181,7 @@ module X where
       <varlistentry>
        <term>Mode flags</term>
        <listitem>
-         <para>For example, <option>--make</option> or <option>-E</option>.
+         <para>For example, <option>&ndash;&ndash;make</option> or <option>-E</option>.
            There may only be a single mode flag on the command line.  The
            available modes are listed in <xref linkend="modes"/>.</para>
        </listitem>
@@ -220,10 +291,20 @@ module X where
   <sect1 id="modes">
     <title>Modes of operation</title>
 
-    <para>GHC's behaviour is firstly controlled by a mode flag.  Only
-    one of these flags may be given, but it does not necessarily need
-    to be the first option on the command-line.  The available modes
-    are:</para>
+    <para>
+      GHC's behaviour is firstly controlled by a mode flag.  Only one
+      of these flags may be given, but it does not necessarily need to
+      be the first option on the command-line.
+    </para>
+
+    <para>
+      If no mode flag is present, then GHC will enter make mode
+      (<xref linkend="make-mode" />) if there are any Haskell source
+      files given on the command line, or else it will link the
+      objects named on the command line to produce an executable.
+    </para>
+
+    <para>The available mode flags are:</para>
 
     <variablelist>
       <varlistentry>
@@ -242,7 +323,7 @@ module X where
       
       <varlistentry>
        <term>
-         <cmdsynopsis><command>ghc --make</command>
+         <cmdsynopsis><command>ghc &ndash;&ndash;make</command>
          </cmdsynopsis>
           <indexterm><primary>make mode</primary></indexterm>
           <indexterm><primary><option>&ndash;&ndash;make</option></primary></indexterm>
@@ -254,6 +335,12 @@ module X where
          likely to be much easier, and faster, than using
          <command>make</command>.  Make mode is described in <xref
          linkend="make-mode"/>.</para>
+
+          <para>
+            This mode is the default if there are any Haskell
+            source files mentioned on the command line, and in this case
+            the <option>&ndash;&ndash;make</option> option can be omitted.
+          </para>
        </listitem>
       </varlistentry>
 
@@ -428,8 +515,7 @@ module X where
       <indexterm><primary><option>&ndash;&ndash;make</option></primary></indexterm>
       <indexterm><primary>separate compilation</primary></indexterm>
       
-      <para>When given the <option>&ndash;&ndash;make</option> option,
-      GHC will build a multi-module Haskell program by following
+      <para>In this mode, GHC will build a multi-module Haskell program by following
       dependencies from one or more root modules (usually just
       <literal>Main</literal>).  For example, if your
       <literal>Main</literal> module is in a file called
@@ -440,12 +526,22 @@ module X where
 ghc &ndash;&ndash;make Main.hs
 </screen>
 
-      <para>The command line may contain any number of source file
-      names or module names; GHC will figure out all the modules in
-      the program by following the imports from these initial modules.
-      It will then attempt to compile each module which is out of
-      date, and finally, if there is a <literal>Main</literal> module,
-      the program will also be linked into an executable.</para>
+      <para>
+        In fact, GHC enters make mode automatically if there are any
+        Haskell source files on the command line and no other mode is
+        specified, so in this case we could just type
+      </para>
+
+<screen>
+ghc Main.hs
+</screen>
+
+      <para>Any number of source file names or module names may be
+      specified; GHC will figure out all the modules in the program by
+      following the imports from these initial modules.  It will then
+      attempt to compile each module which is out of date, and
+      finally, if there is a <literal>Main</literal> module, the
+      program will also be linked into an executable.</para>
 
       <para>The main advantages to using <literal>ghc
       &ndash;&ndash;make</literal> over traditional
index 8348897..519d9cd 100644 (file)
@@ -429,6 +429,14 @@ isDoInteractiveMode :: Mode -> Bool
 isDoInteractiveMode (Right (Right DoInteractive)) = True
 isDoInteractiveMode _ = False
 
+isStopLnMode :: Mode -> Bool
+isStopLnMode (Right (Right (StopBefore StopLn))) = True
+isStopLnMode _ = False
+
+isDoMakeMode :: Mode -> Bool
+isDoMakeMode (Right (Right DoMake)) = True
+isDoMakeMode _ = False
+
 #ifdef GHCI
 isInteractiveMode :: PostLoadMode -> Bool
 isInteractiveMode DoInteractive = True
@@ -462,7 +470,6 @@ isCompManagerMode DoInteractive = True
 isCompManagerMode (DoEval _)    = True
 isCompManagerMode _             = False
 
-
 -- -----------------------------------------------------------------------------
 -- Parsing the mode flag
 
@@ -475,7 +482,7 @@ parseModeFlags args = do
           runCmdLine (processArgs mode_flags args)
                      (Nothing, [], [])
       mode = case mModeFlag of
-             Nothing -> stopBeforeMode StopLn
+             Nothing     -> doMakeMode
              Just (m, _) -> m
       errs = errs1 ++ map (mkGeneralLocated "on the commandline") errs2
   when (not (null errs)) $ ghcError $ errorsToGhcException errs
@@ -519,6 +526,9 @@ mode_flags =
          Supported
 
       ------- primary modes ------------------------------------------------
+  , Flag "c"            (PassFlag (\f -> do setMode (stopBeforeMode StopLn) f
+                                            addFlag "-no-link" f))
+         Supported
   , Flag "M"            (PassFlag (setMode doMkDependHSMode))
          Supported
   , Flag "E"            (PassFlag (setMode (stopBeforeMode anyHsc)))
@@ -536,12 +546,6 @@ mode_flags =
          Supported
   , Flag "e"            (SepArg   (\s -> setMode (doEvalMode s) "-e"))
          Supported
-
-       -- -fno-code says to stop after Hsc but don't generate any code.
-  , Flag "fno-code"     (PassFlag (\f -> do setMode (stopBeforeMode HCc) f
-                                            addFlag "-fno-code" f
-                                            addFlag "-fforce-recomp" f))
-         Supported
   ]
 
 setMode :: Mode -> String -> ModeM ()
@@ -552,6 +556,11 @@ setMode newMode newFlag = do
             Nothing -> ((newMode, newFlag), errs)
             Just (oldMode, oldFlag) ->
                 case (oldMode, newMode) of
+                    -- -c/--make are allowed together, and mean --make -no-link
+                    _ |  isStopLnMode oldMode && isDoMakeMode newMode
+                      || isStopLnMode newMode && isDoMakeMode oldMode ->
+                      ((doMakeMode, "--make"), [])
+
                     -- If we have both --help and --interactive then we
                     -- want showGhciUsage
                     _ | isShowGhcUsageMode oldMode &&
@@ -593,7 +602,6 @@ addFlag s flag = do
 -- Run --make mode
 
 doMake :: [(String,Maybe Phase)] -> Ghc ()
-doMake []    = ghcError (UsageError "no input files")
 doMake srcs  = do
     let (hs_srcs, non_hs_srcs) = partition haskellish srcs
 
@@ -603,6 +611,15 @@ doMake srcs  = do
          phase `notElem` [As, Cc, CmmCpp, Cmm, StopLn]
 
     hsc_env <- GHC.getSession
+
+    -- 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)
+       then oneShot hsc_env StopLn srcs >> GHC.printWarnings
+       else do
+
     o_files <- mapM (\x -> do
                         f <- compileFile hsc_env StopLn x
                         GHC.printWarnings