<para>This section describes how GHC supports separate
compilation.</para>
-
+
<sect2 id="hi-files">
<title>Interface files</title>
<term><option>-i<dirs></option></term>
<listitem>
<para><indexterm><primary><option>-i<dirs></option>
- </primary></indexterm>This flag prepends a colon-separated
+ </primary></indexterm>This flag appends a colon-separated
list of <filename>dirs</filename> to the “import
- directories” list. See also <XRef LinkEnd="recomp">
- for the significance of using relative and absolute
- pathnames in the <option>-i</option> list.</para>
+ directories” list, which initially contains a single
+ entry: <quote>.</quote>.</para>
+
+ <para>This list is scanned before any package directories
+ (see <xref linkend="packages">) when looking for imports,
+ but note that if you have a home module with the same name
+ as a package module then this is likely to cause trouble
+ in other ways, with link errors being the least nasty
+ thing that can go wrong...</para>
+
+ <para>See also <XRef LinkEnd="recomp"> for the
+ significance of using relative and absolute pathnames in
+ the <option>-i</option> list.</para>
</listitem>
</varlistentry>
<variablelist>
<varlistentry>
- <term><option>-ohi</option> <replaceable>file</replaceable></term>
- <indexterm><primary><option>-ohi</option></primary>
- </indexterm>
- <listitem>
- <para>The interface output may be directed to another file
- <filename>bar2/Wurble.iface</filename> with the option
- <option>-ohi bar2/Wurble.iface</option> (not recommended).
- To avoid generating an interface at all, you can say
- <literal>-ohi /dev/null</literal>, for example.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
<term><option>-ddump-hi</option></term>
<indexterm><primary><option>-ddump-hi</option></primary>
</indexterm>
<filename>makefile</filename>, then the old dependencies are
deleted first.</para>
+ <para>Don't forget to use the same <option>-package</option>
+ options on the <literal>ghc -M</literal> command line as you
+ would when compiling; this enables the dependency generator to
+ locate any imported modules that come from packages. The
+ package modules won't be included in the dependencies
+ generated, though (but see the
+ <option>––include-prelude</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
</varlistentry>
<varlistentry>
- <term><option>--exclude-module=<file></option></term>
+ <term><option>––exclude-module=<file></option></term>
<listitem>
<para>Regard <filename><file></filename> as
"stable"; i.e., exclude it from having dependencies on
<varlistentry>
<term><option>-x</option></term>
<listitem>
- <para>same as <option>--exclude-module</option></para>
+ <para>same as <option>––exclude-module</option></para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--exclude-directory=<dirs></option></term>
+ <term><option>––exclude-directory=<dirs></option></term>
<listitem>
<para>Regard the colon-separated list of directories
<filename><dirs></filename> as containing stable,
</varlistentry>
<varlistentry>
- <term><option>--include-module=<file></option></term>
+ <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>
+ the <option>––exclude-directory</option> option.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--include-prelude</option></term>
+ <term><option>––include-prelude</option></term>
<listitem>
- <para>Regard prelude libraries as unstable, i.e.,
- generate dependencies on the prelude modules used
- (including <literal>Prelude</literal>). This option is
- normally only used by the various system libraries. If a
- <option>-package</option> option is used, dependencies
- will also be generated on the library's
- interfaces.</para>
+ <para>Regard modules imported from packages as unstable,
+ i.e., generate dependencies on the package modules used
+ (including <literal>Prelude</literal>, and all other
+ standard Haskell libraries). This option is normally
+ only used by the various system libraries.</para>
</listitem>
</varlistentry>
</variablelist>
recursive modules properly without the manual construction of
interface files, is (allegedly) in the works.</para>
</sect2>
+
+
+ <sect2 id="orphan-modules">
+ <title>Orphan modules and instance declarations</title>
+
+<para> Haskell specifies that when compiling module M, any instance
+declaration in any module "below" M is visible. (Module A is "below"
+M if A is imported directly by M, or if A is below a module that M imports directly.)
+In principle, GHC must therefore read the interface files of every module below M,
+just in case they contain an instance declaration that matters to M. This would
+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
+GHC has to visit that interface file anyway. Example:</para>
+<ProgramListing>
+ module A where
+ instance C a => D (T a) where ...
+ data T a = ...
+</ProgramListing>
+<para> The instance declaration is only relevant if the type T is in use, and if
+so, GHC will have visited A's interface file to find T's definition. </para>
+
+<para> The only problem comes when a module contains an instance declaration
+and GHC has no other reason for visiting the module. Example:
+<ProgramListing>
+ module Orphan where
+ instance C a => D (T 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>
+<itemizedlist>
+ <listitem> <para> An <emphasis>orphan module</emphasis>
+ <indexterm><primary>orphan module</primary></indexterm>
+ contains at least one <emphasis>orphan instance</emphasis> or at
+ 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
+ to be in module A; it must be the declaration of D or T.</para>
+ </listitem>
+
+ <listitem><para> A rewrite rule in a module M is an <emphasis>orphan rule</emphasis>
+ <indexterm><primary>orphan rule</primary></indexterm>
+ if none of the variables, type constructors,
+ or classes that are free in the left hand side of the rule are declared in M.
+ </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><para>
+You can identify an orphan module by looking in its interface file, M.hi. If there is a ``!'' on
+the first line, GHC considers it an orphan module.
+</para>
+</sect2>
+
</sect1>
<!-- Emacs stuff: