separate_compilation.sgml 23.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
  <sect1 id="separate-compilation">
    <title>Separate compilation</title>
    
    <indexterm><primary>separate compilation</primary></indexterm>
    <indexterm><primary>recompilation checker</primary></indexterm>
    <indexterm><primary>make and recompilation</primary></indexterm>
    
    <para>This section describes how GHC supports separate
    compilation.</para>
10

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
    <sect2 id="hi-files">
      <title>Interface files</title>
      
      <indexterm><primary>interface files</primary></indexterm>
      <indexterm><primary><literal>.hi</literal> files</primary></indexterm>
      
      <para>When GHC compiles a source file <filename>A.hs</filename>
      which contains a module <literal>A</literal>, say, it generates
      an object <filename>A.o</filename>, <emphasis>and</emphasis> a
      companion <emphasis>interface file</emphasis>
      <filename>A.hi</filename>.  The interface file is not intended
      for human consumption, as you'll see if you take a look at one.
      It's merely there to help the compiler compile other modules in
      the same program.</para>

      <para>NOTE: In general, the name of a file containing module
      <literal>M</literal> should be named <filename>M.hs</filename>
      or <literal>M.lhs</literal>.  The only exception to this rule is
      module <literal>Main</literal>, which can be placed in any
      file.<indexterm><primary>filenames</primary><secondary>for
      modules</secondary> </indexterm></para>
      
      <para>The interface file for <literal>A</literal> contains
      information needed by the compiler when it compiles any module
      <literal>B</literal> that imports <literal>A</literal>, whether
      directly or indirectly.  When compiling <literal>B</literal>,
      GHC will read <filename>A.hi</filename> to find the details that
      it needs to know about things defined in
      <literal>A</literal>.</para>

      <para>The interface file may contain all sorts of things that
      aren't explicitly exported from <literal>A</literal> by the
      programmer.  For example, even though a data type is exported
      abstractly, <filename>A.hi</filename> will contain the full data
      type definition.  For small function definitions,
      <filename>A.hi</filename> will contain the complete definition
      of the function.  For bigger functions,
      <filename>A.hi</filename> will contain strictness information
      about the function.  And so on.  GHC puts much more information
      into <filename>.hi</filename> files when optimisation is turned
      on with the <option>-O</option> flag (see <xref
      linkend="options-optimise">).  Without <option>-O</option> it
      puts in just the minimum; with <option>-O</option> it lobs in a
      whole pile of stuff.  <indexterm><primary>optimsation, effect on
      .hi files</primary></indexterm></para>

      <para><filename>A.hi</filename> should really be thought of as a
      compiler-readable version of <filename>A.o</filename>.  If you
      use a <filename>.hi</filename> file that wasn't generated by the
      same compilation run that generates the <filename>.o</filename>
      file the compiler may assume all sorts of incorrect things about
      <literal>A</literal>, resulting in core dumps and other
      unpleasant happenings.</para>

    </sect2>

    <sect2 id="options-finding-imports">
      <title>Finding interface files</title>

      <indexterm><primary>interface files, finding them</primary></indexterm>
      <indexterm><primary>finding interface files</primary></indexterm>

      <para>In your program, you import a module
      <literal>Foo</literal> by saying <literal>import Foo</literal>.
      GHC goes looking for an interface file,
      <filename>Foo.hi</filename>.  It has a builtin list of
      directories (notably including <filename>.</filename>) where it
      looks.</para>

      <variablelist>

	<varlistentry>
	  <term><option>-i&lt;dirs&gt;</option></term>
	  <listitem>
	    <para><indexterm><primary><option>-i&lt;dirs&gt;</option>
            </primary></indexterm>This flag prepends a colon-separated
            list of <filename>dirs</filename> to the &ldquo;import
            directories&rdquo; list.  See also <XRef LinkEnd="recomp">
            for the significance of using relative and absolute
            pathnames in the <option>-i</option> list.</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><option>-i</option></term>
	  <listitem>
	    <para>resets the &ldquo;import directories&rdquo; list
	    back to nothing.</para>
	  </listitem>
	</varlistentry>

      </variablelist>

      <para>See also the section on packages (<xref
      linkend="packages">), which describes how to use installed
      libraries.</para>

    </sect2>

    <Sect2 id="hi-options">
      <title>Other options related to interface files</title>
      <indexterm><primary>interface files, options</primary></indexterm>

      <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>
	  <listitem>
	    <para>Dumps the new interface to standard output.</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><option>-ddump-hi-diffs</option></term>
	  <indexterm><primary><option>-ddump-hi-diffs</option></primary>
	  </indexterm>
	  <listitem>
	    <para>The compiler does not overwrite an existing
            <filename>.hi</filename> interface file if the new one is
            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>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><option>-ddump-minimal-imports</option></term>
	  <indexterm><primary><option>-ddump-minimal-imports</option></primary>
	  </indexterm>
	  <listitem>
	    <para>Dump to the file "M.imports" (where M is the module
            being compiled) a "minimal" set of import declarations.
            You can safely replace all the import declarations in
            "M.hs" with those found in "M.imports".  Why would you
            want to do that?  Because the "minimal" imports (a) import
            everything explicitly, by name, and (b) import nothing
            that is not required.  It can be quite painful to maintain
            this property by hand, so this flag is intended to reduce
            the labour.</para>
	  </listitem>
	</varlistentry>
      </variablelist>
	
    </sect2>

    <sect2 id="recomp">
      <title>The recompilation checker</title>

      <indexterm><primary>recompilation checker</primary></indexterm>

      <variablelist>
	<varlistentry>
	  <term><option>-no-recomp</option></term>
	  <indexterm><primary><option>-recomp</option></primary></indexterm>
	  <indexterm><primary><option>-no-recomp</option></primary></indexterm>
	  <listitem>
	    <para>Turn off recompilation checking (which is on by
            default).  Recompilation checking normally stops
            compilation early, leaving an existing
            <filename>.o</filename> file in place, if it can be
            determined that the module does not need to be
            recompiled.</para>
	  </listitem>
	</varlistentry>
      </variablelist>
      
      <para>In the olden days, GHC compared the newly-generated
      <filename>.hi</filename> 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 <filename>.hi</filename> file were not
      recompiled.</para>

      <para>This doesn't work any more.  Suppose module
      <literal>C</literal> imports module <literal>B</literal>, and
      <literal>B</literal> imports module <literal>A</literal>.  So
      changes to <filename>A.hi</filename> should force a
      recompilation of <literal>C</literal>.  And some changes to
      <literal>A</literal> (changing the definition of a function that
      appears in an inlining of a function exported by
      <literal>B</literal>, say) may conceivably not change
      <filename>B.hi</filename> one jot.  So now&hellip;</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 reompilation 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 &ldquo;Compilation IS NOT
      required&rdquo;.  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>

    </sect2>

    <sect2 id="using-make">
      <title>Using <command>make</command></title>

      <indexterm><primary><literal>make</literal></primary></indexterm>

      <para>It is reasonably straightforward to set up a
      <filename>Makefile</filename> to use with GHC, assuming you name
      your source files the same as your modules.  Thus:</para>

<ProgramListing>
HC      = ghc
HC_OPTS = -cpp $(EXTRA_HC_OPTS)

SRCS = Main.lhs Foo.lhs Bar.lhs
OBJS = Main.o   Foo.o   Bar.o

.SUFFIXES : .o .hs .hi .lhs .hc .s

cool_pgm : $(OBJS)
        rm $@
        $(HC) -o $@ $(HC_OPTS) $(OBJS)

# Standard suffix rules
.o.hi:
        @:

.lhs.o:
        $(HC) -c $&#60; $(HC_OPTS)

.hs.o:
        $(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
</ProgramListing>

      <para>(Sophisticated <command>make</command> variants may
      achieve some of the above more elegantly.  Notably,
      <command>gmake</command>'s pattern rules let you write the more
      comprehensible:</para>

<ProgramListing>
%.o : %.lhs
        $(HC) -c $&#60; $(HC_OPTS)
</ProgramListing>

      <para>What we've shown should work with any
      <command>make</command>.)</para>

      <para>Note the cheesy <literal>.o.hi</literal> rule: It records
      the dependency of the interface (<filename>.hi</filename>) file
      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 the inter-module dependencies at the end of the
      Makefile, which take the form</para>

<ProgramListing>
Foo.o Foo.hc Foo.s    : Baz.hi          # Foo imports Baz
</ProgramListing>

      <para>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>

      <sect3 id="sec-makefile-dependencies">
	<title>Dependency generation</title>
	<indexterm><primary>dependencies in Makefiles</primary></indexterm>
	<indexterm><primary>Makefile dependencies</primary></indexterm>

	<para>Putting inter-dependencies of the form <literal>Foo.o :
        Bar.hi</literal> into your <filename>Makefile</filename> by
        hand is rather error-prone.  Don't worry, GHC has support for
        automatically generating the required dependencies.  Add the
        following to your <filename>Makefile</filename>:</para>

<ProgramListing>
depend :
        ghc -M $(HC_OPTS) $(SRCS)
</ProgramListing>

	<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
        append the needed dependencies to your
        <filename>Makefile</filename>.</para>

	<para>In general, if module <literal>A</literal> contains the
        line

<programlisting>
import B ...blah...
</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

<programlisting>
import {-# SOURCE #-} B ...blah...
</programlisting>

	then <command>ghc -M</command> will generate a dependency
	line of the form:

<programlisting>
A.o : B.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
       target.</para>

        <para>By default, <command>ghc -M</command> generates all the
        dependencies, and then concatenates them onto the end of
        <filename>makefile</filename> (or
        <filename>Makefile</filename> if <filename>makefile</filename>
        doesn't exist) bracketed by the lines "<literal>&num; DO NOT
        DELETE: Beginning of Haskell dependencies</literal>" and
        "<literal>&num; DO NOT DELETE: End of Haskell
        dependencies</literal>".  If these lines already exist in the
        <filename>makefile</filename>, then the old dependencies are
        deleted first.</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>
      
	The options which affect dependency generation are:</para>
	
	<variablelist>
	  <varlistentry>
	    <term><option>-w</option></term>
	    <listitem>
	      <para>Turn off warnings about interface file shadowing.</para>
	    </listitem>
	  </varlistentry>
	  
	  <varlistentry>
	    <term><option>-f</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
              <filename>.depend</filename> and then
              <command>include</command> the file
              <filename>.depend</filename> into
              <filename>Makefile</filename>.</para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><option>-o &lt;osuf&gt;</option></term>
	    <listitem>
	      <para>Use <filename>.&lt;osuf&gt;</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 &lt;suf&gt;</option></term>
	    <listitem>
	      <para>Make extra dependencies that declare that files
              with suffix
              <filename>.&lt;suf&gt;&lowbar;&lt;osuf&gt;</filename>
              depend on interface files with suffix
              <filename>.&lt;suf&gt;&lowbar;hi</filename>, or (for
              <literal>&lcub;-&num; SOURCE &num;-&rcub;</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
              <filename>.hi</filename>,
              <filename>.a&lowbar;hc</filename> on
              <filename>.a&lowbar;hi</filename>, and
              <filename>.b&lowbar;hc</filename> on
              <filename>.b&lowbar;hi</filename>.  (Useful in
              conjunction with NoFib "ways".)</para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><option>--exclude-module=&lt;file&gt;</option></term>
	    <listitem>
	      <para>Regard <filename>&lt;file&gt;</filename> as
              "stable"; i.e., exclude it from having dependencies on
              it.</para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><option>-x</option></term>
	    <listitem>
	      <para>same as <option>--exclude-module</option></para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><option>--exclude-directory=&lt;dirs&gt;</option></term>
	    <listitem>
	      <para>Regard the colon-separated list of directories
              <filename>&lt;dirs&gt;</filename> as containing stable,
              don't generate any dependencies on modules
              therein.</para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term><option>--include-module=&lt;file&gt;</option></term>
	    <listitem>
	      <para>Regard <filename>&lt;file&gt;</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-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>
	    </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>
__interface A 1 0 where
__export A TA{MkTA} ;
1 newtype TA = MkTA PrelBase.Int ;
</ProgramListing>

      <para>The syntax is essentially the same as a normal
      <filename>.hi</filename> file (unfortunately), so you can
      usually tailor an existing <filename>.hi</filename> file to make
      a <filename>.hi-boot</filename> file.</para>

      <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 number &ldquo;1&rdquo; after
      &ldquo;&lowbar;&lowbar;interface A&rdquo; gives the version
      number of module A; it is incremented whenever anything in A's
      interface file changes.  In a normal interface file, the
      &ldquo;0&rdquo; is the version number of the compiler which
      generated the interface file; it is used to ensure that we don't
      mix-and-match interface files between compiler versions.
      Leaving it as zero in an <literal>hi-boot</literal> file turns
      off this check.</para>

      <para>The number &ldquo;1&rdquo; at the beginning of a
      declaration is the <emphasis>version number</emphasis> of that
      declaration: for the purposes of <filename>.hi-boot</filename>
      files these can all be set to 1.  All names must be fully
      qualified with the <emphasis>original</emphasis> module that an
      object comes from: for example, the reference to
      <literal>Int</literal> in the interface for <literal>A</literal>
      comes from <literal>PrelBase</literal>, which is a module
      internal to GHC's prelude.  It's a pain, but that's the way it
      is.</para>

      <para>If you want an <literal>hi-boot</literal> file to export a
      data type, but you don't want to give its constructors (because
      the constructors aren't used by the SOURCE-importing module),
      you can write simply:</para>

<ProgramListing>
__interface A 1 0 where
__export A TA;
1 data TA
</ProgramListing>

      <para>(You must write all the type parameters, but leave out the
      '=' and everything that follows it.)</para>

      <para><emphasis>Note:</emphasis> This is all a temporary
      solution, a version of the compiler that handles mutually
      recursive modules properly without the manual construction of
      interface files, is (allegedly) in the works.</para>
    </sect2>
  </sect1>

<!-- Emacs stuff:
     ;;; Local Variables: ***
     ;;; mode: sgml ***
     ;;; sgml-parent-document: ("using.sgml" "book" "chapter") ***
     ;;; End: ***
 -->