[project @ 2005-10-28 15:51:15 by simonmar]
[ghc-hetmet.git] / ghc / docs / users_guide / separate_compilation.xml
index 9a6b7e3..fc44fe6 100644 (file)
           <filename>Main.hs</filename>, and put the resulting
           executable in <filename>foo.exe</filename> (not
           <filename>foo</filename>).</para>
+
+          <para>If you use <command>ghc --make</command> and you don't
+          use the <option>-o</option>, the name GHC will choose
+          for the executable will be based on the name of the file
+          containing the module <literal>Main</literal>. 
+          Note that with GHC the <literal>Main</literal> module doesn't
+          have to be put in file <filename>Main.hs</filename>.
+          Thus both
+<programlisting>
+   ghc --make Prog
+</programlisting>
+          and
+<programlisting>
+   ghc --make Prog.hs
+</programlisting>
+          will produce <filename>Prog</filename> (or
+          <filename>Prog.exe</filename> if you are on Windows).</para>
          </listitem>
        </varlistentry>
 
@@ -326,6 +343,23 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
 
        <varlistentry>
          <term>
+            <option>-stubdir</option>  <replaceable>dir</replaceable>
+            <indexterm><primary><option>-stubdir</option></primary></indexterm>
+          </term>
+         <listitem>
+           <para>Redirects all generated FFI stub files into
+           <replaceable>dir</replaceable>.  Stub files are generated when the
+           Haskell source contains a <literal>foreign export</literal> or
+           <literal>foreign import "&amp;wrapper"</literal> declaration (see <xref
+             linkend="foreign-export-ghc" />).  The <option>-stubdir</option>
+             option behaves in exactly the same way as <option>-odir</option>
+             and <option>-hidir</option> with respect to hierarchical
+           modules.</para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>
             <option>-osuf</option> <replaceable>suffix</replaceable>
             <indexterm><primary><option>-osuf</option></primary></indexterm>
           </term>
@@ -369,7 +403,7 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
        </varlistentry>
       </variablelist>
     </sect2>
-
+  
     <sect2 id="keeping-intermediates">
       <title>Keeping Intermediate Files</title>
       <indexterm><primary>intermediate files, saving</primary>
@@ -612,6 +646,174 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
 
     </sect2>
 
+    <sect2 id="mutual-recursion">
+      <title>How to compile mutually recursive modules</title>
+
+      <indexterm><primary>module system, recursion</primary></indexterm>
+      <indexterm><primary>recursion, between modules</primary></indexterm>
+
+      <para>GHC supports the compilation of mutually recursive modules.
+      This section explains how.</para>
+
+      <para>Every cycle in the module import graph must be broken by a <filename>hs-boot</filename> file.
+      Suppose that modules <filename>A.hs</filename> and <filename>B.hs</filename> are Haskell source files, 
+      thus:
+<programlisting>
+module A where
+    import B( TB(..) )
+    
+    newtype TA = MkTA Int
+    
+    f :: TB -&#62; TA
+    f (MkTB x) = MkTA x
+
+module B where
+    import {-# SOURCE #-} A( TA(..) )
+    
+    data TB = MkTB !Int
+    
+    g :: TA -&#62; TB
+    g (MkTA x) = MkTB x
+</programlisting>
+<indexterm><primary><literal>hs-boot</literal>
+      files</primary></indexterm> <indexterm><primary>importing,
+      <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
+version of <filename>A.hs</filename>, thus:
+<programlisting>
+module A where
+    newtype TA = MkTA Int
+</programlisting>
+</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 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
+</programlisting>
+</para>
+<para>There are several points to note here:
+<itemizedlist>
+<listitem>
+  <para>The file <filename>A.hs-boot</filename> is a programmer-written source file.
+  It must live in the same directory as its parent source file <filename>A.hs</filename>.
+  Currently, if you use a literate source file <filename>A.lhs</filename> you must
+  also use a literate boot file, <filename>A.lhs-boot</filename>; and vice versa.
+  </para></listitem>
+
+<listitem><para>
+  A <filename>hs-boot</filename> file is compiled by GHC, just like a <filename>hs</filename> file:
+<programlisting>
+  ghc -c A.hs-boot
+</programlisting>
+When a hs-boot file <filename>A.hs-boot</filename> 
+   is compiled, it is checked for scope and type errors.
+   When its parent module <filename>A.hs</filename> is compiled, the two are compared, and
+   an error is reported if the two are inconsistent.
+   </para></listitem>
+   
+       <listitem>
+         <para> Just as compiling <filename>A.hs</filename> produces an
+           interface file <filename>A.hi</filename>, and an object file
+           <filename>A.o</filename>, so compiling
+           <filename>A.hs-boot</filename> produces an interface file
+           <filename>A.hi-boot</filename>, and an pseudo-object file
+           <filename>A.o-boot</filename>: </para>
+
+         <itemizedlist>
+           <listitem>
+             <para>The pseudo-object file <filename>A.o-boot</filename> is
+               empty (don't link it!), but it is very useful when using a
+               Makefile, to record when the <filename>A.hi-boot</filename> was
+               last brought up to date (see <xref
+                 linkend="using-make"/>).</para>
+           </listitem>
+
+           <listitem>
+             <para>The <filename>hi-boot</filename> generated by compiling a
+               <filename>hs-boot</filename> file is in the same
+               machine-generated binary format as any other GHC-generated
+               interface file (e.g. <filename>B.hi</filename>). You can
+               display its contents with <command>ghc
+                 --show-iface</command>. If you specify a directory for
+               interface files, the <option>-ohidir</option> flag, then that
+               affects <filename>hi-boot</filename> files
+               too.</para>
+           </listitem>
+         </itemizedlist>
+       </listitem>
+
+   <listitem><para> If hs-boot files are considered distinct from their parent source
+   files, and if a <literal>{-# SOURCE #-}</literal> import is considered to refer to the
+   hs-boot file, then the module import graph must have no cycles.  The command
+   <command>ghc -M</command> will report an error if a cycle is found.
+   </para></listitem>
+
+   <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
+   compile and link, to ensure that <literal>M</literal>'s implementation is included in
+   the final program.
+   </para></listitem>
+</itemizedlist>
+</para>
+<para>
+A hs-boot file need only contain the bare
+      minimum of information needed to get the bootstrapping process
+      started.  For example, it doesn't need to contain declarations
+      for <emphasis>everything</emphasis> that module
+      <literal>A</literal> exports, only the things required by the
+      module(s) that import <literal>A</literal> recursively.</para>
+<para>A hs-boot file is written in a subset of Haskell:
+<itemizedlist>
+<listitem><para> The module header (including the export list), and import statements, are exactly as in
+Haskell, and so are the scoping rules.  
+   Hence, to mention a non-Prelude type or class, you must import it.</para></listitem>
+   
+<listitem><para> There must be no value declarations, but there can be type signatures for
+values.  For example:
+<programlisting>
+  double :: Int -&#62; Int
+</programlisting>
+</para></listitem>
+<listitem><para> Fixity declarations are exactly as in Haskell.</para></listitem>
+<listitem><para> Type synonym declarations are exactly as in Haskell.</para></listitem>
+<listitem><para> A data type declaration can either be given in full, exactly as in Haskell, or it 
+can be given abstractly, by omitting the '=' sign and everything that follows.  For example:
+<programlisting>
+  data T a b
+</programlisting>
+           In a <emphasis>source</emphasis> program
+         this would declare TA to have no constructors (a GHC extension: see <xref linkend="nullary-types"/>),
+         but in an hi-boot file it means "I don't know or care what the constructors are".
+           This is the most common form of data type declaration, because it's easy to get right.
+         You <emphasis>can</emphasis> also write out the constructors but, if you do so, you must write
+         it out precisely as in its real definition.</para>
+         <para>
+           If you do not write out the constructors, you may need to give a kind 
+           annotation (<xref linkend="sec-kinding"/>), to tell
+           GHC the kind of the type variable, if it is not "*".  (In source files, this is worked out
+           from the way the type variable is used in the constructors.)  For example:
+<programlisting>
+  data R (x :: * -&#62; *) y
+</programlisting>
+</para></listitem>
+<listitem><para> Class declarations is exactly as in Haskell, except that you may not put
+default method declarations.  You can also omit all the class methods entirely.
+</para></listitem>
+<listitem><para> Do not include instance declarations. There is a complication to do with
+how the dictionary functions are named.  It may well work, but it's not a well-tested feature.
+ </para></listitem>
+</itemizedlist>
+</para>
+    </sect2>
+
+
     <sect2 id="using-make">
       <title>Using <command>make</command></title>
 
@@ -644,6 +846,15 @@ cool_pgm : $(OBJS)
 .hs.o:
         $(HC) -c $&#60; $(HC_OPTS)
 
+.o-boot.hi-boot:
+        @:
+
+.lhs-boot.o-boot:
+        $(HC) -c $&#60; $(HC_OPTS)
+
+.hs-boot.o-boot:
+        $(HC) -c $&#60; $(HC_OPTS)
+
 # Inter-module dependencies
 Foo.o Foo.hc Foo.s    : Baz.hi          # Foo imports Baz
 Main.o Main.hc Main.s : Foo.hi Baz.hi   # Main imports Foo and Baz
@@ -667,23 +878,30 @@ Main.o Main.hc Main.s : Foo.hi Baz.hi   # Main imports Foo and Baz
       on the source.  The rule says a <filename>.hi</filename> file
       can be made from a <filename>.o</filename> file by
       doing&hellip;nothing.  Which is true.</para>
+      <para> Note that the suffix rules are all repeated twice, once
+      for normal Haskell source files, and once for <filename>hs-boot</filename>
+      files (see <xref linkend="mutual-recursion"/>).</para>
 
-      <para>Note the inter-module dependencies at the end of the
-      Makefile, which take the form</para>
+      <para>Note also the inter-module dependencies at the end of the
+      Makefile, which take the form
 
 <programlisting>
 Foo.o Foo.hc Foo.s    : Baz.hi          # Foo imports Baz
 </programlisting>
 
-      <para>They tell <command>make</command> that if any of
+      They tell <command>make</command> that if any of
       <literal>Foo.o</literal>, <literal>Foo.hc</literal> or
       <literal>Foo.s</literal> have an earlier modification date than
       <literal>Baz.hi</literal>, then the out-of-date file must be
       brought up to date.  To bring it up to date,
       <literal>make</literal> looks for a rule to do so; one of the
-      preceding suffix rules does the job nicely.</para>
+      preceding suffix rules does the job nicely.  These dependencies
+      can be generated automatically by <command>ghc</command>; see 
+      <xref linkend="sec-makefile-dependencies"/></para>
 
-      <sect3 id="sec-makefile-dependencies">
+ </sect2>
+
+      <sect2 id="sec-makefile-dependencies">
        <title>Dependency generation</title>
        <indexterm><primary>dependencies in Makefiles</primary></indexterm>
        <indexterm><primary>Makefile dependencies</primary></indexterm>
@@ -702,42 +920,49 @@ depend :
        <para>Now, before you start compiling, and any time you change
         the <literal>imports</literal> in your program, do
         <command>make depend</command> before you do <command>make
-        cool&lowbar;pgm</command>.  <command>ghc -M</command> will
+        cool&lowbar;pgm</command>.  The command <command>ghc -M</command> will
         append the needed dependencies to your
         <filename>Makefile</filename>.</para>
 
-       <para>In general, if module <literal>A</literal> contains the
-        line
-
+       <para>In general, <command>ghc -M Foo</command> does the following.
+       For each module <literal>M</literal> in the set 
+       <literal>Foo</literal> plus all its imports (transitively),
+       it adds to the Makefile:
+       <itemizedlist>
+       <listitem><para>A line recording the dependence of the object file on the source file.
 <programlisting>
-import B ...blah...
+M.o : M.hs
 </programlisting>
-
-       then <command>ghc -M</command> will generate a dependency line
-        of the form:
-
-<programlisting>
-A.o : B.hi
-</programlisting>
-
-       If module <literal>A</literal> contains the line
-
+(or <literal>M.lhs</literal> if that is the filename you used).
+       </para></listitem>
+       <listitem><para> For each import declaration <literal>import X</literal> in <literal>M</literal>,
+       a line recording the dependence of <literal>M</literal> on <literal>X</literal>:
 <programlisting>
-import {-# SOURCE #-} B ...blah...
-</programlisting>
-
-       then <command>ghc -M</command> will generate a dependency
-       line of the form:
-
+M.o : X.hi
+</programlisting></para></listitem>
+       <listitem><para> For each import declaration <literal>import {-# SOURCE #-} X</literal> in <literal>M</literal>,
+       a line recording the dependence of <literal>M</literal> on <literal>X</literal>:
 <programlisting>
-A.o : B.hi-boot
+M.o : X.hi-boot
 </programlisting>
-
        (See <xref linkend="mutual-recursion"/> for details of
-       <literal>hi-boot</literal> style interface files.)  If
-       <literal>A</literal> imports multiple modules, then there will
-       be multiple lines with <filename>A.o</filename> as the
+       <literal>hi-boot</literal> style interface files.)
+      </para></listitem>
+        </itemizedlist> 
+       If <literal>M</literal> imports multiple modules, then there will
+       be multiple lines with <filename>M.o</filename> as the
        target.</para>
+       <para>There is no need to list all of the source files as arguments to the <command>ghc -M</command> command;
+       <command>ghc</command> traces the dependencies, just like <command>ghc --make</command>
+       (a new feature in GHC 6.4).</para>
+
+    <para>Note that <literal>ghc -M</literal> needs to find a <emphasis>source
+       file</emphasis> for each module in the dependency graph, so that it can
+      parse the import declarations and follow dependencies.  Any pre-compiled
+      modules without source files must therefore belong to a
+      package<footnote><para>This is a change in behaviour relative to 6.2 and
+       earlier.</para>
+      </footnote>.</para>
 
         <para>By default, <command>ghc -M</command> generates all the
         dependencies, and then concatenates them onto the end of
@@ -756,7 +981,7 @@ A.o : B.hi-boot
        locate any imported modules that come from packages.  The
        package modules won't be included in the dependencies
        generated, though (but see the
-       <option>&ndash;&ndash;include-prelude</option> option below).</para>
+       <option>&ndash;&ndash;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
@@ -780,6 +1005,17 @@ ghc -M -optdep-f -optdep.depend ...
          </varlistentry>
 
          <varlistentry>
+           <term><option>-v2</option></term>
+           <listitem>
+             <para>Print a full list of the module depenencies to stdout.
+                   (This is the standard verbosity flag, so the list will
+             also be displayed with <option>-v3</option> and
+             <option>-v4</option>;
+             <xref linkend ="options-help"/>.)</para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
            <term><option>-f</option> <replaceable>file</replaceable></term>
            <listitem>
              <para>Use <replaceable>file</replaceable> as the makefile,
@@ -867,167 +1103,23 @@ ghc -M -optdep-f -optdep.depend ...
          </varlistentry>
 
          <varlistentry>
-           <term><option>&ndash;&ndash;include-prelude</option></term>
+           <term><option>&ndash;&ndash;include-pkg-deps</option></term>
            <listitem>
              <para>Regard modules imported from packages as unstable,
-              i.e., generate dependencies on the package modules used
+              i.e., generate dependencies on any imported package modules
               (including <literal>Prelude</literal>, and all other
-              standard Haskell libraries).  This option is normally
+              standard Haskell libraries).  Dependencies are not traced
+             recursively into packages; dependencies are only generated for
+             home-package modules on external-package modules directly imported
+             by the home package module.
+             This option is normally
               only used by the various system libraries.</para>
            </listitem>
          </varlistentry>
        </variablelist>
 
-      </sect3>
     </sect2>
 
-    <sect2 id="mutual-recursion">
-      <title>How to compile mutually recursive modules</title>
-
-      <indexterm><primary>module system, recursion</primary></indexterm>
-      <indexterm><primary>recursion, between modules</primary></indexterm>
-
-      <para>Currently, the compiler does not have proper support for
-      dealing with mutually recursive modules:</para>
-
-<programlisting>
-module A where
-
-import B
-
-newtype TA = MkTA Int
-
-f :: TB -&#62; TA
-f (MkTB x) = MkTA x
---------
-module B where
-
-import A
-
-data TB = MkTB !Int
-
-g :: TA -&#62; TB
-g (MkTA x) = MkTB x
-</programlisting>
-
-      <para>When compiling either module A and B, the compiler will
-      try (in vain) to look for the interface file of the other. So,
-      to get mutually recursive modules off the ground, you need to
-      hand write an interface file for A or B, so as to break the
-      loop.  These hand-written interface files are called
-      <literal>hi-boot</literal> files, and are placed in a file
-      called <filename>&lt;module&gt;.hi-boot</filename>.  To import
-      from an <literal>hi-boot</literal> file instead of the standard
-      <filename>.hi</filename> file, use the following syntax in the
-      importing module: <indexterm><primary><literal>hi-boot</literal>
-      files</primary></indexterm> <indexterm><primary>importing,
-      <literal>hi-boot</literal> files</primary></indexterm></para>
-
-<programlisting>
-import {-# SOURCE #-} A
-</programlisting>
-
-      <para>The hand-written interface need only contain the bare
-      minimum of information needed to get the bootstrapping process
-      started.  For example, it doesn't need to contain declarations
-      for <emphasis>everything</emphasis> that module
-      <literal>A</literal> exports, only the things required by the
-      module that imports <literal>A</literal> recursively.</para>
-
-      <para>For the example at hand, the boot interface file for A
-      would look like the following:</para>
-
-<programlisting>
-module A where
-newtype TA = MkTA GHC.Base.Int
-</programlisting>
-
-      <para>Notice that we only put the declaration for the newtype
-      <literal>TA</literal> in the <literal>hi-boot</literal> file,
-      not the signature for <function>f</function>, since
-      <function>f</function> isn't used by <literal>B</literal>.</para>
-
-      <para>The syntax is similar to a normal Haskell source file, but
-      with some important differences:</para>
-
-      <itemizedlist>
-       <listitem>
-         <para>Local entities (ones defined in the same <literal>hi-boot</literal> file may
-          be mentioned unqualified, but non-local entities (ones defined in other modules)
-          must be qualified with their
-         <emphasis>original</emphasis> defining module.  Qualifying
-         by a module which just re-exports the entity won't do.  In
-         particular, most <literal>Prelude</literal> entities aren't
-         actually defined in the <literal>Prelude</literal> (see for
-         example <literal>GHC.Base.Int</literal> in the above
-         example).  HINT: to find out the fully-qualified name for
-         entities in the <literal>Prelude</literal> (or anywhere for
-         that matter), try using GHCi's
-         <literal>:info</literal> command, eg.</para>
-<programlisting>Prelude> :m -Prelude
-> :i IO.IO
--- GHC.IOBase.IO is a type constructor
-newtype GHC.IOBase.IO a
-...</programlisting>
-       </listitem>
-       <listitem>
-         <para>Only <literal>data</literal>, <literal>type</literal>,
-         <literal>newtype</literal>, <literal>class</literal>, and
-         type signature declarations may be included. You cannot declare
-         <literal>instances</literal> or derive them automatically with 
-          a <literal>deriving</literal> clause.</para>
-</listitem>
-
-<listitem> <para>For <literal>data</literal> or <literal>newtype</literal> declaration, you may omit all
-the constructors, by omitting the '=' and everything that follows it:
-<programlisting>
-module A where
-  data TA
-</programlisting>
-           In a <emphasis>source</emphasis> program
-         this would declare TA to have no constructors (a GHC extension: see <xref linkend="nullary-types"/>),
-         but in an hi-boot file it means "I don't know or care what the constructors are".
-           This is the most common form of data type declaration, because it's easy to get right.</para>
-         <para>
-         You <emphasis>can</emphasis> also write out the constructors but, if you do so, you must write
-         it out precisely as in its real definition.
-           It is especially delicate if you use a strictness annotation "!",
-         with or without an <literal>{-# UNPACK #-}</literal> pragma.  In a source file
-         GHC may or may not choose to unbox the argument, but in an hi-boot file it's
-         assumed that you express the <emphasis>outcome</emphasis> of this decision.
-           (So in the cases where GHC decided not to unpack, you must not use the pragma.)
-           Tread with care.</para>
-         <para>
-           Regardless of whether you write the constructors, you must write all the type parameters,
-           <emphasis>including their kinds</emphasis>
-           if they are not '*'.  (You can give explicit kinds in source files too (<xref linkend="sec-kinding"/>),
-           but you <emphasis>must</emphasis> do so in hi-boot files.)</para>
-       </listitem>
-
-<listitem><para>
-       In a <literal>class</literal> declararation, you may not specify any class operations; that is, 
-         there can be no <literal>where</literal> part.  If you want to use the class operations in a recursive
-         way, declare them in the <literal>hi-boot</literal> file with separate, overloaded type signatures, thus:
-<programlisting>
-   class Num a
-   (+) :: Num a => a -> a -> a
-</programlisting>
-         </para>
-       </listitem>
-      </itemizedlist>
-
-<para>If <literal>M.hi-boot</literal> mentions an entity <literal>N.f</literal>, defined in some other
-module <literal>N</literal>, then GHC will by default go hunting for <literal>N.hi</literal>. If module
-<literal>N</literal> is not yet compiled either, GHC won't look for <literal>N.hi-boot</literal>; it'll just
-complain.  To fix this, in the source file that uses 
-<literal>import {-# SOURCE #-} M</literal>, add 
-<literal>import {-# SOURCE #-} N()</literal>.  (The "()" says that you don't want to import anything into
-your current scope, and will prevent unused-import warnings.)  You only need this if no other imported module 
-depends on <literal>N.hi-boot</literal>.</para>
-
-    </sect2>
-
-
     <sect2 id="orphan-modules">
       <title>Orphan modules and instance declarations</title>