dots replaced by the directory separator ('/' or '\', depending
on the system), and <replaceable>extension</replaceable> is a
source extension (<literal>hs</literal>, <literal>lhs</literal>)
- if we are in <option>--make</option> mode and GHCi, or
+ if we are in <option>--make</option> mode or GHCi, or
<replaceable>hisuf</replaceable> otherwise.</para>
<para>For example, suppose the search path contains directories
<para>This isn't the whole story: GHC also looks for modules in
pre-compiled libraries, known as packages. See the section on
- packages (<xref linkend="packages"/>), for details.</para>
+ packages (<xref linkend="packages"/>) for details.</para>
</sect2>
<sect2 id="options-output">
<replaceable>dir</replaceable>. For example:</para>
<screen>
-$ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
+$ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `uname -m`
</screen>
<para>The object files, <filename>Foo.o</filename>,
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>-outputdir</option> <replaceable>dir</replaceable>
+ <indexterm><primary><option>-outputdir</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>The <option>-outputdir</option> option is shorthand for
+ the combination
+ of <option>-odir</option>, <option>-hidir</option>,
+ and <option>-stubdir</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>
<option>-osuf</option> <replaceable>suffix</replaceable>
<variablelist>
<varlistentry>
<term>
+ <option>-keep-hc-file</option>,
<option>-keep-hc-files</option>
+ <indexterm><primary><option>-keep-hc-file</option></primary></indexterm>
<indexterm><primary><option>-keep-hc-files</option></primary></indexterm>
</term>
<listitem>
<varlistentry>
<term>
+ <option>-keep-s-file</option>,
<option>-keep-s-files</option>
+ <indexterm><primary><option>-keep-s-file</option></primary></indexterm>
<indexterm><primary><option>-keep-s-files</option></primary></indexterm>
</term>
<listitem>
<varlistentry>
<term>
+ <option>-keep-raw-s-file</option>,
<option>-keep-raw-s-files</option>
+ <indexterm><primary><option>-keep-raw-s-file</option></primary></indexterm>
<indexterm><primary><option>-keep-raw-s-files</option></primary></indexterm>
</term>
<listitem>
the same as the old one; this is friendly to
<command>make</command>. When an interface does change,
it is often enlightening to be informed. The
- <option>-ddump-hi-diffs</option> option will make GHC run
- <command>diff</command> on the old and new
- <filename>.hi</filename> files.</para>
+ <option>-ddump-hi-diffs</option> option will make GHC
+ report the differences between the old and
+ new <filename>.hi</filename> files.</para>
</listitem>
</varlistentry>
<indexterm><primary><option>--show-iface</option></primary></indexterm>
</term>
<listitem>
- <para>Where <replaceable>file</replaceable> is the name of
+ <para>where <replaceable>file</replaceable> is the name of
an interface file, dumps the contents of that interface in
- a human-readable (ish) format.</para>
+ a human-readable (ish) format. See <xref linkend="modes"/>.</para>
</listitem>
</varlistentry>
</variablelist>
<literal>B</literal>, say) may conceivably not change
<filename>B.hi</filename> one jot. So now…</para>
- <para>GHC keeps a version number on each interface file, and on
- each type signature within the interface file. It also keeps in
- every interface file a list of the version numbers of everything
- it used when it last compiled the file. If the source file's
- modification date is earlier than the <filename>.o</filename>
- file's date (i.e. the source hasn't changed since the file was
- last compiled), and the recompilation checking is on, GHC will be
- clever. It compares the version numbers on the things it needs
- this time with the version numbers on the things it needed last
- time (gleaned from the interface file of the module being
- compiled); if they are all the same it stops compiling rather
- early in the process saying “Compilation IS NOT
- required”. What a beautiful sight!</para>
-
- <para>Patrick Sansom had a workshop paper about how all this is
- done (though the details have changed quite a bit). <ulink
- url="mailto:sansom@dcs.gla.ac.uk">Ask him</ulink> if you want a
- copy.</para>
+ <para>GHC calculates a fingerprint (in fact an MD5 hash) of each
+ interface file, and of each declaration within the interface
+ file. It also keeps in every interface file a list of the
+ fingerprints of everything it used when it last compiled the
+ file. If the source file's modification date is earlier than
+ the <filename>.o</filename> file's date (i.e. the source hasn't
+ changed since the file was last compiled), and the recompilation
+ checking is on, GHC will be clever. It compares the fingerprints
+ on the things it needs this time with the fingerprints
+ on the things it needed last time (gleaned from the
+ interface file of the module being compiled); if they are all
+ the same it stops compiling early in the process saying
+ “Compilation IS NOT required”. What a beautiful
+ sight!</para>
+
+ <para>You can read
+ about <ulink url="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/RecompilationAvoidance">how
+ all this works</ulink> in the GHC commentary.</para>
</sect2>
<literal>hi-boot</literal> files</primary></indexterm>
Here <filename>A</filename> imports <filename>B</filename>, but <filename>B</filename> imports
<filename>A</filename> with a <literal>{-# SOURCE #-}</literal> pragma, which breaks the
-circular dependency. For every module <filename>A.hs</filename> that is <literal>{-# SOURCE #-}</literal>-imported
-in this way there must exist a souce file <literal>A.hs-boot</literal>. This file contains an abbreviated
+circular dependency. Every loop in the module import graph must be broken by a <literal>{-# SOURCE #-}</literal> import;
+or, equivalently, the module import graph must be acyclic if <literal>{-# SOURCE #-}</literal> imports are ignored.
+</para>
+<para>For every module <filename>A.hs</filename> that is <literal>{-# SOURCE #-}</literal>-imported
+in this way there must exist a source file <literal>A.hs-boot</literal>. This file contains an abbreviated
version of <filename>A.hs</filename>, thus:
<programlisting>
module A where
</para>
<para>To compile these three files, issue the following commands:
<programlisting>
- ghc -c A.hs-boot -- Poduces A.hi-boot, A.o-boot
+ ghc -c A.hs-boot -- Produces A.hi-boot, A.o-boot
ghc -c B.hs -- Consumes A.hi-boot, produces B.hi, B.o
ghc -c A.hs -- Consumes B.hi, produces A.hi, A.o
ghc -o foo A.o B.o -- Linking the program
<listitem><para> A module <literal>M</literal> that is
<literal>{-# SOURCE #-}</literal>-imported in a program will usually also be
ordinarily imported elsewhere. If not, <command>ghc --make</command>
- automatically adds <literal>M</literal> to the set of moudles it tries to
+ automatically adds <literal>M</literal> to the set of modules it tries to
compile and link, to ensure that <literal>M</literal>'s implementation is included in
the final program.
</para></listitem>
<programlisting>
data R (x :: * -> *) y
</programlisting>
-You cannot use <literal>deriving</literal> on a data type declaration; write in
+You cannot use <literal>deriving</literal> on a data type declaration; write an
<literal>instance</literal> declaration instead.
</para></listitem>
<listitem><para> Class declarations is exactly as in Haskell, except that you may not put
<option>––include-pkg-deps</option> option below).</para>
<para>The dependency generation phase of GHC can take some
- additional options, which you may find useful. For historical
- reasons, each option passed to the dependency generator from
- the GHC command line must be preceded by
- <literal>-optdep</literal>. For example, to pass <literal>-f
- .depend</literal> to the dependency generator, you say
-
-<screen>
-ghc -M -optdep-f -optdep.depend ...
-</screen>
+ additional options, which you may find useful.
The options which affect dependency generation are:</para>
<term><option>-ddump-mod-cycles</option></term>
<listitem>
<para>Display a list of the cycles in the module graph. This is
- useful when trying to eliminate such cycles. You do not need the <literal>-optdep</literal> prefix
- for this flag.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-w</option></term>
- <listitem>
- <para>Turn off warnings about interface file shadowing.</para>
+ useful when trying to eliminate such cycles.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v2</option></term>
<listitem>
- <para>Print a full list of the module depenencies to stdout.
+ <para>Print a full list of the module dependencies to stdout.
(This is the standard verbosity flag, so the list will
also be displayed with <option>-v3</option> and
<option>-v4</option>;
</varlistentry>
<varlistentry>
- <term><option>-f</option> <replaceable>file</replaceable></term>
+ <term><option>-dep-makefile</option> <replaceable>file</replaceable></term>
<listitem>
<para>Use <replaceable>file</replaceable> as the makefile,
rather than <filename>makefile</filename> or
<filename>Makefile</filename>. If
<replaceable>file</replaceable> doesn't exist,
<command>mkdependHS</command> creates it. We often use
- <option>-f .depend</option> to put the dependencies in
+ <option>-dep-makefile .depend</option> to put the dependencies in
<filename>.depend</filename> and then
<command>include</command> the file
<filename>.depend</filename> into
</listitem>
</varlistentry>
-<!-- Retired with the move away from 'mkdependHS'.
<varlistentry>
- <term><option>-o <osuf></option></term>
- <listitem>
- <para>Use <filename>.<osuf></filename> as the
- "target file" suffix ( default: <literal>o</literal>).
- Multiple <option>-o</option> flags are permitted
- (GHC2.05 onwards). Thus "<option>-o hc -o o</option>"
- will generate dependencies for <filename>.hc</filename>
- and <filename>.o</filename> files.</para>
- </listitem>
- </varlistentry>
--->
- <varlistentry>
- <term><option>-s <suf></option></term>
+ <term><option>-dep-suffix <suf></option></term>
<listitem>
<para>Make extra dependencies that declare that files
with suffix
<filename>.<suf>_hi</filename>, or (for
<literal>{-# SOURCE #-}</literal>
imports) on <filename>.hi-boot</filename>. Multiple
- <option>-s</option> flags are permitted. For example,
- <option>-o hc -s a -s b</option> will make dependencies
- for <filename>.hc</filename> on
+ <option>-dep-suffix</option> flags are permitted. For example,
+ <option>-dep-suffix a -dep-suffix b</option>
+ will make dependencies
+ for <filename>.hs</filename> on
<filename>.hi</filename>,
- <filename>.a_hc</filename> on
+ <filename>.a_hs</filename> on
<filename>.a_hi</filename>, and
- <filename>.b_hc</filename> on
+ <filename>.b_hs</filename> on
<filename>.b_hi</filename>. (Useful in
conjunction with NoFib "ways".)</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>-x</option></term>
- <listitem>
- <para>same as <option>––exclude-module</option></para>
- </listitem>
- </varlistentry>
-
-<!-- Not currently implemented:
- <varlistentry>
- <term><option>––exclude-directory=<dirs></option></term>
- <listitem>
- <para>Regard the colon-separated list of directories
- <filename><dirs></filename> as containing stable,
- don't generate any dependencies on modules
- therein.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>––include-module=<file></option></term>
- <listitem>
- <para>Regard <filename><file></filename> as not
- "stable"; i.e., generate dependencies on it (if
- any). This option is normally used in conjunction with
- the <option>––exclude-directory</option> option.</para>
- </listitem>
- </varlistentry>
--->
-
- <varlistentry>
<term><option>––include-pkg-deps</option></term>
<listitem>
<para>Regard modules imported from packages as unstable,
be a disaster in practice, so GHC tries to be clever. </para>
<para>In particular, if an instance declaration is in the same module as the definition
-of any type or class mentioned in the head of the instance declaration, then
+of any type or class mentioned in the <emphasis>head</emphasis> of the instance declaration
+(the part after the “<literal>=></literal>”; see <xref linkend="instance-rules"/>), then
GHC has to visit that interface file anyway. Example:</para>
<programlisting>
module A where
class C a where ...
</programlisting>
Here, neither D nor T is declared in module Orphan.
-We call such modules ``orphan modules'',
-defined thus:</para>
+We call such modules “orphan modules”.
+GHC identifies orphan modules, and visits the interface file of
+every orphan module below the module being compiled. This is usually
+wasted work, but there is no avoiding it. You should therefore do
+your best to have as few orphan modules as possible.
+</para>
+<para>
+Functional dependencies complicate matters. Suppose we have:
+<programlisting>
+ module B where
+ instance E T Int where ...
+ data T = ...
+</programlisting>
+Is this an orphan module? Apparently not, because <literal>T</literal>
+is declared in the same module. But suppose class <literal>E</literal> had a
+functional dependency:
+<programlisting>
+ module Lib where
+ class E x y | y -> x where ...
+</programlisting>
+Then in some importing module M, the constraint <literal>(E a Int)</literal> should be "improved" by setting
+<literal>a = T</literal>, <emphasis>even though there is no explicit mention
+of <literal>T</literal> in M</emphasis>.</para>
+
+These considerations lead to the following definition of an orphan module:
<itemizedlist>
<listitem> <para> An <emphasis>orphan module</emphasis>
<indexterm><primary>orphan module</primary></indexterm>
least one <emphasis>orphan rule</emphasis>.</para> </listitem>
<listitem><para> An instance declaration in a module M is an <emphasis>orphan instance</emphasis> if
- <indexterm><primary>orphan instance</primary></indexterm>
- none of the type constructors
- or classes mentioned in the instance head (the part after the ``<literal>=></literal>'') are declared
- in M.</para>
-
- <para> Only the instance head counts. In the example above, it is not good enough for C's declaration
+ <indexterm><primary>orphan instance</primary></indexterm>
+<itemizedlist>
+<listitem><para>
+ The class of the instance declaration is not declared in M, and
+</para></listitem>
+<listitem>
+<para> <emphasis>Either</emphasis> the class has no functional dependencies, and none of the type constructors
+ in the instance head is declared in M; <emphasis>or</emphasis> there
+ is a functional dependency for which none of the type constructors mentioned
+ in the <emphasis>non-determined</emphasis> part of the instance head is defined in M.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ <para> Only the instance head
+ counts. In the example above, it is not good enough for C's declaration
to be in module A; it must be the declaration of D or T.</para>
</listitem>
</itemizedlist>
-<para> GHC identifies orphan modules, and visits the interface file of
-every orphan module below the module being compiled. This is usually
-wasted work, but there is no avoiding it. You should therefore do
-your best to have as few orphan modules as possible.
+<para>If you use the flag <option>-fwarn-orphans</option>, GHC will warn you
+if you are creating an orphan module.
+Like any warning, you can switch the warning off with <option>-fno-warn-orphans</option>,
+and <option>-Werror</option>
+will make the compilation fail if the warning is issued.
</para>
-
-<para> You can identify an orphan module by looking in its interface
+<para>
+You can identify an orphan module by looking in its interface
file, <filename>M.hi</filename>, using the
-<option>--show-iface</option>. If there is a ``!'' on the first line,
-GHC considers it an orphan module.
+<link linkend="modes"><option>--show-iface</option> mode</link>. If there is a <literal>[orphan module]</literal> on the
+first line, GHC considers it an orphan module.
</para>
</sect2>