[project @ 1997-07-05 01:26:55 by sof]
authorsof <unknown>
Sat, 5 Jul 1997 01:26:55 +0000 (01:26 +0000)
committersof <unknown>
Sat, 5 Jul 1997 01:26:55 +0000 (01:26 +0000)
New section on iface files; updated recompilation bits

ghc/docs/users_guide/recomp.lit

index 5b3abe8..55c64f4 100644 (file)
 %************************************************************************
 %*                                                                      *
-\section[recomp]{The GHC recompilation checker (and using `make')}
+\section[separate-compilation]{Separate compilation}
+\index{separate compilation}
 \index{recompilation checker}
 \index{make and recompilation}
 %*                                                                      *
 %************************************************************************
 
-WIth the introduction of Haskell~1.3, the module system (nicely
-improved, thank you very much) requires a substantially different
-implementation, which we did (as of release GHC~2.01).
-
-We have taken a fairly radical approach and implemented a ``go to the
-horse's mouth'' scheme; that is, when seeking out information about an
-entity \tr{Foo.bar}, GHC will always look in the interface for
-\tr{Foo}---no matter what interface {\em told us} about \tr{Foo.bar}
-(via re-exporting and whatnot).
-
-This ``horse's mouth'' scheme removes some of the most unsavoury
-aspects of GHC~0.2x's behaviour (because of picking up duff
-information about re-exported entities).  However, the keen-minded
-user will see that it makes it difficult to maintain
-\tr{make}-friendly dependencies between modules.
-
-Enter the ``recompilation checker'', which you invoke merely by adding
-a \tr{-recomp} option\index{-recomp option} to your GHC command line.
-(You should also create ordinary `make' dependencies; there's an
-example of how to do this in \sectionref{mkdependHS}.)
-
-GHC will now start ``compiling'' much more often than in the old days,
-but it will frequently bail out quickly, saying the recompile is
-\tr{NOT NEEDED}.  What a beautiful sight!
-
-%The recompilation checker is not finished.  Its main faults are:
-%(a)~it doesn't yet do the right things for instance declarations;
-%(b)~it doesn't do anything about pragmas (happily, GHC~2.01 doesn't
-%produce any); (c)~it has no good solution for mutually-recursive
-%modules.
-
-Patrick Sansom has a workshop paper about how all these things should
-be done.  Ask him (email: \tr{sansom}) if you want a copy.
+This section describes how GHC supports separate compilation.
+
+\subsection[hi-files]{Interface files}
+
+When GHC compiles a source module @A@, it generates an object @A.o@, {\em and} a
+companion {\em interface file} @A.hi@.   The interface file
+contains information needed by the compiler when it compiles any module @B@ that
+imports @A@, whether directly or indirectly.  When compiling @B@, GHC will
+read @A.hi@ to find the details that it needs to know about things defined in @A@.
+
+Furthermore, when compiling module @C@ which imports @B@, GHC may decide that it
+needs to know something about @A@ --- for example, @B@ might export a function
+that involves a type defined in @A@.  In this case, GHC will go and read @A.hi@ even
+though @C@ does not explicitly import @A@ at all.
+
+The interface file may contain all sorts of things that aren't explicitly
+exported from @A@ by the programmer.  For example, even though a data type is exported
+abstractly, @A.hi@ will contain the full data type definition.  For small function
+definitions, @A.hi@ will contain the complete definition of the function.  For
+bigger functions, @A.hi@ will contain strictness information about the function.  And so on.
+GHC puts much more information into @.hi@ files when you use @-O@.  Without @-O@
+it puts in just the minimum; with @-O@ it lobs in a whole pile of stuff.
+
+@A.hi@ should really be thought of as a compiler-readable version of @A.o@.
+If you use a @.hi@ file that wasn't generated by the same compilation run that
+generates the @.o@ file the compiler may assume all sorts of incorrect things about @A@,
+resulting in core dumps and other unpleasant happenings.
+
+In the olden days, GHC compared the newly-generated @.hi@ file with the previous version;
+if they were identical, it left the old one alone and didn't change its modification date.
+In consequence, importers of a module with an unchanged output @.hi@ file were not recompiled.
+
+This doesn't work any more.  In our earlier example, module @C@ does
+not import module @A@ directly, yet changes to @A.hi@ should force a
+recompilation of @C@.  And some changes to @A@ (changing the
+definition of a function that appears in an inlining of a function
+exported by @B@, say) may conceivably not change @B.hi@ one jot.  So
+now
+
+
+\subsection[recomp]{The recompilation checker}
+
+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 @.o@ file's date (i.e. the source hasn't changed since the
+file was last compiled), and you give GHC the @-recomp@ flag, then 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 ``Recompilation not required''.  What a beautiful
+sight!
+
+It's still an experimental feature (that's why @-recomp@ is off by
+default), so tell us if you think it doesn't work.
+
+Patrick Sansom has a workshop paper about how all this is 
+done.  Ask him (email: \tr{sansom}) if you want a copy.
+
+\subsection{Using @make@}
+
+It is reasonably straightforward to set up a \tr{Makefile} to use with
+GHC, assuming you name your source files the same as your modules.
+Thus:
+\begin{verbatim}
+HC      = ghc
+HC_OPTS = -cpp $(EXTRA_HC_OPTS)
+
+SRCS = Main.lhs Foo.lhs Bar.lhs
+OBJS = Main.o   Foo.o   Bar.o
+
+.SUFFIXES : .o .hi .lhs .hc .s
+
+cool_pgm : $(OBJS)
+        $(RM) $@
+        $(HC) -o $@ $(HC_OPTS) $(OBJS)
+
+# Standard suffix rules
+.o.hi:
+       @:
+
+.lhs.o:
+        $(RM) $@
+        $(HC) -c $< $(HC_OPTS)
+
+.hs.o:
+        $(RM) $@
+        $(HC) -c $< $(HC_OPTS)
+
+# Optional
+.hc.o:
+        $(RM) $@
+        $(HC) -c $< $(HC_OPTS)
+
+# Optional
+.s.o:
+        $(RM) $@
+        $(HC) -c $< $(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
+\end{verbatim}
+
+(Sophisticated \tr{make} variants may achieve some of the above more
+elegantly.  Notably, @gmake@'s pattern rules let you write the more comprehensible:
+\begin{verbatim}
+%.o : %.lhs
+        $(RM) $@
+        $(HC) -c $< $(HC_OPTS)
+\end{verbatim}
+What we've shown should work with any \tr{make}.)
+
+Note the cheesy \tr{.o.hi} rule: It records the dependency of the
+interface (\tr{.hi}) file on the source.  The rule says a \tr{.hi}
+file can be made from a \tr{.o} file by doing... nothing.  Which is
+true.
+
+Note the inter-module dependencies at the end of the Makefile, which take the form
+\begin{verbatim}
+Foo.o Foo.hc Foo.s    : Baz.hi         # Foo imports Baz
+\end{verbatim}
+They tell @make@ that if any of @Foo.o@, @Foo.hc@ or @Foo.s@ have
+an earlier modification date than @Baz.hi@, then the out-of-date
+file must be brought up to date.  To bring it up to date, @make@ looks
+for a rule to do so; one of the preceding suffix rules does the job nicely.
+
+Putting inter-dependencies of the form \tr{Foo.o : Bar.hi} into your
+\tr{Makefile} by hand is rather error-prone.  Don't worry---never
+fear, \tr{mkdependHS} is here! (and is distributed as part of GHC)
+Add the following to your \tr{Makefile}:
+\begin{verbatim}
+depend :
+        mkdependHS -- $(HC_OPTS) -- $(SRCS)
+\end{verbatim}
+Now, before you start compiling, and any time you change the
+\tr{imports} in your program, do \tr{make depend} before you do
+\tr{make cool_pgm}.  \tr{mkdependHS} will append the needed
+dependencies to your \tr{Makefile}.  @mkdependHS@ is fully
+describe in \Sectionref{mkdependHS}.
+
+
+
+
+
+
+A few caveats about this simple scheme: (a)~You may need to compile
+some modules explicitly to create their interfaces in the first place
+(e.g., \tr{make Bar.o} to create \tr{Bar.hi}).  (b)~You may have to
+type \tr{make} more than once for the dependencies to have full
+effect.  However, a \tr{make} run that does nothing {\em does} mean
+``everything's up-to-date.''  (c) This scheme will work with
+mutually-recursive modules but, again, it may take multiple
+iterations to ``settle.''
+
+
+