Commit 7828bf3e authored by Simon Marlow's avatar Simon Marlow

--make is now the default (#3515), and -fno-code works with --make (#3783)

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.
parent b1710d98
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -5,6 +5,77 @@
<indexterm><primary>GHC, using</primary></indexterm>
<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>
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment