summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
Diffstat (limited to 'ghc')
-rw-r--r--ghc/docs/users_guide/recomp.lit196
1 files changed, 162 insertions, 34 deletions
diff --git a/ghc/docs/users_guide/recomp.lit b/ghc/docs/users_guide/recomp.lit
index 5b3abe8f17..55c64f467f 100644
--- a/ghc/docs/users_guide/recomp.lit
+++ b/ghc/docs/users_guide/recomp.lit
@@ -1,41 +1,169 @@
%************************************************************************
%* *
-\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.''
+
+
+