diff options
author | Ben Gamari <ben@smart-cactus.org> | 2015-10-01 01:08:41 +0200 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2015-10-03 09:44:48 +0200 |
commit | 4fd6207ec6960c429e6a1bcbe0282f625010f52a (patch) | |
tree | 26e1f43199fbde80f26225f7409b5c00ce8792a9 /docs/users_guide/separate_compilation.xml | |
parent | 9ed700bb4128b1cbf59d99d725c44d7a0bfb1de6 (diff) | |
download | haskell-4fd6207ec6960c429e6a1bcbe0282f625010f52a.tar.gz |
Move user's guide to ReStructuredText
Diffstat (limited to 'docs/users_guide/separate_compilation.xml')
-rw-r--r-- | docs/users_guide/separate_compilation.xml | 1351 |
1 files changed, 0 insertions, 1351 deletions
diff --git a/docs/users_guide/separate_compilation.xml b/docs/users_guide/separate_compilation.xml deleted file mode 100644 index 121458f4e6..0000000000 --- a/docs/users_guide/separate_compilation.xml +++ /dev/null @@ -1,1351 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> - <sect1 id="separate-compilation"> - <title>Filenames and 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 what files GHC expects to find, what - files it creates, where these files are stored, and what options - affect this behaviour.</para> - - <para>Note that this section is written with - <firstterm>hierarchical modules</firstterm> in mind (see <xref - linkend="hierarchical-modules"/>); hierarchical modules are an - extension to Haskell 98 which extends the lexical syntax of - module names to include a dot ‘.’. Non-hierarchical - modules are thus a special case in which none of the module names - contain dots.</para> - - <para>Pathname conventions vary from system to system. In - particular, the directory separator is - ‘<literal>/</literal>’ on Unix systems and - ‘<literal>\</literal>’ on Windows systems. In the - sections that follow, we shall consistently use - ‘<literal>/</literal>’ as the directory separator; - substitute this for the appropriate character for your - system.</para> - - <sect2 id="source-files"> - <title>Haskell source files</title> - - <indexterm><primary>filenames</primary></indexterm> - - <para>Each Haskell source module should be placed in a file on - its own.</para> - - <para>Usually, the file should be named after the module name, - replacing dots in the module name by directory separators. For - example, on a Unix system, the module <literal>A.B.C</literal> - should be placed in the file <literal>A/B/C.hs</literal>, - relative to some base directory. If the module is not going to - be imported by another module (<literal>Main</literal>, for - example), then you are free to use any filename for it.</para> - - <indexterm><primary>unicode</primary></indexterm> - - <para> GHC assumes that source files are - ASCII<indexterm><primary>ASCII</primary></indexterm> or - UTF-8<indexterm><primary>UTF-8</primary></indexterm> only, other - encodings<indexterm><primary>encoding</primary></indexterm> are - not recognised. However, invalid UTF-8 sequences will be - ignored in comments, so it is possible to use other encodings - such as - Latin-1<indexterm><primary>Latin-1</primary></indexterm>, as - long as the non-comment source code is ASCII only.</para> - </sect2> - - <sect2 id="output-files"> - <title>Output files</title> - - <indexterm><primary>interface files</primary></indexterm> - <indexterm><primary><literal>.hi</literal> files</primary></indexterm> - <indexterm><primary>object files</primary></indexterm> - <indexterm><primary><literal>.o</literal> files</primary></indexterm> - - <para>When asked to compile a source file, GHC normally - generates two files: an <firstterm>object file</firstterm>, and - an <firstterm>interface file</firstterm>. </para> - - <para>The object file, which normally ends in a - <literal>.o</literal> suffix, contains the compiled code for the - module.</para> - - <para>The interface file, - which normally ends in a <literal>.hi</literal> suffix, contains - the information that GHC needs in order to compile further - modules that depend on this module. It contains things like the - types of exported functions, definitions of data types, and so - on. It is stored in a binary format, so don't try to read one; - use the <option>--show-iface</option> option instead (see <xref - linkend="hi-options"/>).</para> - - <para>You should think of the object file and the interface file as a - pair, since the interface file is in a sense a compiler-readable - description of the contents of the object file. If the - interface file and object file get out of sync for any reason, - then the compiler may end up making assumptions about the object - file that aren't true; trouble will almost certainly follow. - For this reason, we recommend keeping object files and interface - files in the same place (GHC does this by default, but it is - possible to override the defaults as we'll explain - shortly).</para> - - <para>Every module has a <emphasis>module name</emphasis> - defined in its source code (<literal>module A.B.C where - ...</literal>).</para> - - <para>The name of the object file generated by GHC is derived - according to the following rules, where - <replaceable>osuf</replaceable> is the object-file suffix (this - can be changed with the <option>-osuf</option> option).</para> - - <itemizedlist> - <listitem> - <para>If there is no <option>-odir</option> option (the - default), then the object filename is derived from the - source filename (ignoring the module name) by replacing the - suffix with <replaceable>osuf</replaceable>.</para> - </listitem> - <listitem> - <para>If - <option>-odir</option> <replaceable>dir</replaceable> - has been specified, then the object filename is - <replaceable>dir</replaceable>/<replaceable>mod</replaceable>.<replaceable>osuf</replaceable>, - where <replaceable>mod</replaceable> is the module name with - dots replaced by slashes. GHC will silently create the necessary directory - structure underneath <replaceable>dir</replaceable>, if it does not - already exist.</para> - </listitem> - </itemizedlist> - - <para>The name of the interface file is derived using the same - rules, except that the suffix is - <replaceable>hisuf</replaceable> (<literal>.hi</literal> by - default) instead of <replaceable>osuf</replaceable>, and the - relevant options are <option>-hidir</option> and - <option>-hisuf</option> instead of <option>-odir</option> and - <option>-osuf</option> respectively.</para> - - <para>For example, if GHC compiles the module - <literal>A.B.C</literal> in the file - <filename>src/A/B/C.hs</filename>, with no - <literal>-odir</literal> or <literal>-hidir</literal> flags, the - interface file will be put in <literal>src/A/B/C.hi</literal> - and the object file in <literal>src/A/B/C.o</literal>.</para> - - <para>For any module that is imported, GHC requires that the - name of the module in the import statement exactly matches the - name of the module in the interface file (or source file) found - using the strategy specified in <xref linkend="search-path"/>. - This means that for most modules, the source file name should - match the module name.</para> - - <para>However, note that it is reasonable to have a module - <literal>Main</literal> in a file named - <filename>foo.hs</filename>, but this only works because GHC - never needs to search for the interface for module - <literal>Main</literal> (because it is never imported). It is - therefore possible to have several <literal>Main</literal> - modules in separate source files in the same directory, and GHC - will not get confused.</para> - - <para>In batch compilation mode, the name of the object file can - also be overridden using the <option>-o</option> option, and the - name of the interface file can be specified directly using the - <option>-ohi</option> option.</para> - </sect2> - - <sect2 id="search-path"> - <title>The search path</title> - - <indexterm><primary>search path</primary> - </indexterm> - <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>. - In <option>--make</option> mode or GHCi, GHC will look for a - source file for <literal>Foo</literal> and arrange to compile it - first. Without <option>--make</option>, GHC will look for the - interface file for <literal>Foo</literal>, which should have - been created by an earlier compilation of - <literal>Foo</literal>. GHC uses the same strategy in each of - these cases for finding the appropriate file.</para> - - <para>This strategy is as follows: GHC keeps a list of - directories called the <firstterm>search path</firstterm>. For - each of these directories, it tries appending - <replaceable>basename</replaceable><literal>.</literal><replaceable>extension</replaceable> - to the directory, and checks whether the file exists. The value - of <replaceable>basename</replaceable> is the module name with - dots replaced by the directory separator ('/' or '\', depending - on the system), and <replaceable>extension</replaceable> is a - source extension (<literal>hs</literal>, <literal>lhs</literal>) - if we are in <option>--make</option> mode or GHCi, or - <replaceable>hisuf</replaceable> otherwise.</para> - - <para>For example, suppose the search path contains directories - <literal>d1</literal>, <literal>d2</literal>, and - <literal>d3</literal>, and we are in <literal>--make</literal> - mode looking for the source file for a module - <literal>A.B.C</literal>. GHC will look in - <literal>d1/A/B/C.hs</literal>, <literal>d1/A/B/C.lhs</literal>, - <literal>d2/A/B/C.hs</literal>, and so on.</para> - - <para>The search path by default contains a single directory: - <quote>.</quote> (i.e. the current directory). The following - options can be used to add to or change the contents of the - search path:</para> - - <variablelist> - <varlistentry> - <term><option>-i<replaceable>dirs</replaceable></option></term> - <listitem> - <para><indexterm><primary><option>-i<replaceable>dirs</replaceable></option> - </primary></indexterm>This flag appends a colon-separated - list of <filename>dirs</filename> to the search path.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-i</option></term> - <listitem> - <para>resets the search path back to nothing.</para> - </listitem> - </varlistentry> - </variablelist> - - <para>This isn't the whole story: GHC also looks for modules in - pre-compiled libraries, known as packages. See the section on - packages (<xref linkend="packages"/>) for details.</para> - </sect2> - - <sect2 id="options-output"> - <title>Redirecting the compilation output(s)</title> - - <indexterm><primary>output-directing options</primary></indexterm> - <indexterm><primary>redirecting compilation output</primary></indexterm> - - <variablelist> - <varlistentry> - <term> - <option>-o</option> <replaceable>file</replaceable> - <indexterm><primary><option>-o</option></primary></indexterm> - </term> - <listitem> - <para>GHC's compiled output normally goes into a - <filename>.hc</filename>, <filename>.o</filename>, etc., - file, depending on the last-run compilation phase. The - option <option>-o <replaceable>file</replaceable></option> - re-directs the output of that last-run phase to - <replaceable>file</replaceable>.</para> - - <para>Note: this “feature” can be - counterintuitive: <command>ghc -C -o foo.o - foo.hs</command> will put the intermediate C code in the - file <filename>foo.o</filename>, name - notwithstanding!</para> - - <para>This option is most often used when creating an - executable file, to set the filename of the executable. - For example: -<screen> ghc -o prog --make Main</screen> - - will compile the program starting with module - <literal>Main</literal> and put the executable in the - file <literal>prog</literal>.</para> - - <para>Note: on Windows, if the result is an executable - file, the extension "<filename>.exe</filename>" is added - if the specified filename does not already have an - extension. Thus -<programlisting> - ghc -o foo Main.hs -</programlisting> - will compile and link the module - <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> - - <varlistentry> - <term> - <option>-odir</option> <replaceable>dir</replaceable> - <indexterm><primary><option>-odir</option></primary></indexterm> - </term> - <listitem> - <para>Redirects object files to directory - <replaceable>dir</replaceable>. For example:</para> - -<screen> -$ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `uname -m` -</screen> - - <para>The object files, <filename>Foo.o</filename>, - <filename>Bar.o</filename>, and - <filename>Bumble.o</filename> would be put into a - subdirectory named after the architecture of the executing - machine (<filename>x86</filename>, - <filename>mips</filename>, etc).</para> - - <para>Note that the <option>-odir</option> option does - <emphasis>not</emphasis> affect where the interface files - are put; use the <option>-hidir</option> option for that. - In the above example, they would still be put in - <filename>parse/Foo.hi</filename>, - <filename>parse/Bar.hi</filename>, and - <filename>gurgle/Bumble.hi</filename>.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-ohi</option> <replaceable>file</replaceable> - <indexterm><primary><option>-ohi</option></primary></indexterm> - </term> - <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).</para> - - <para>WARNING: if you redirect the interface file - somewhere that GHC can't find it, then the recompilation - checker may get confused (at the least, you won't get any - recompilation avoidance). We recommend using a - combination of <option>-hidir</option> and - <option>-hisuf</option> options instead, if - possible.</para> - - <para>To avoid generating an interface at all, you could - use this option to redirect the interface into the bit - bucket: <literal>-ohi /dev/null</literal>, for - example.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-hidir</option> <replaceable>dir</replaceable> - <indexterm><primary><option>-hidir</option></primary></indexterm> - </term> - <listitem> - <para>Redirects all generated interface files into - <replaceable>dir</replaceable>, instead of the - default.</para> - </listitem> - </varlistentry> - - <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 "&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>-dumpdir</option> <replaceable>dir</replaceable> - <indexterm><primary><option>-dumpdir</option></primary></indexterm> - </term> - <listitem> - <para>Redirects all dump files into - <replaceable>dir</replaceable>. Dump files are generated when - <literal>-ddump-to-file</literal> is used with other - <literal>-ddump-*</literal> flags.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-outputdir</option> <replaceable>dir</replaceable> - <indexterm><primary><option>-outputdir</option></primary></indexterm> - </term> - <listitem> - <para>The <option>-outputdir</option> option is shorthand for - the combination - of <option>-odir</option>, <option>-hidir</option>, - <option>-stubdir</option> and <option>-dumpdir</option>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-osuf</option> <replaceable>suffix</replaceable> - <indexterm><primary><option>-osuf</option></primary></indexterm> - </term> - <term> - <option>-hisuf</option> <replaceable>suffix</replaceable> - <indexterm><primary><option>-hisuf</option></primary></indexterm> - </term> - <term> - <option>-hcsuf</option> <replaceable>suffix</replaceable> - <indexterm><primary><option>-hcsuf</option></primary></indexterm> - </term> - <listitem> - <para>The <option>-osuf</option> - <replaceable>suffix</replaceable> will change the - <literal>.o</literal> file suffix for object files to - whatever you specify. We use this when compiling - libraries, so that objects for the profiling versions of - the libraries don't clobber the normal ones.</para> - - <para>Similarly, the <option>-hisuf</option> - <replaceable>suffix</replaceable> will change the - <literal>.hi</literal> file suffix for non-system - interface files (see <xref linkend="hi-options"/>).</para> - - <para>Finally, the option <option>-hcsuf</option> - <replaceable>suffix</replaceable> will change the - <literal>.hc</literal> file suffix for compiler-generated - intermediate C files.</para> - - <para>The <option>-hisuf</option>/<option>-osuf</option> - game is particularly useful if you want to compile a - program both with and without profiling, in the same - directory. You can say: - <screen> - ghc ...</screen> - to get the ordinary version, and - <screen> - ghc ... -osuf prof.o -hisuf prof.hi -prof -auto-all</screen> - to get the profiled version.</para> - </listitem> - </varlistentry> - </variablelist> - </sect2> - - <sect2 id="keeping-intermediates"> - <title>Keeping Intermediate Files</title> - <indexterm><primary>intermediate files, saving</primary> - </indexterm> - <indexterm><primary><literal>.hc</literal> files, saving</primary> - </indexterm> - <indexterm><primary><literal>.ll</literal> files, saving</primary> - </indexterm> - <indexterm><primary><literal>.s</literal> files, saving</primary> - </indexterm> - - <para>The following options are useful for keeping certain - intermediate files around, when normally GHC would throw these - away after compilation:</para> - - <variablelist> - <varlistentry> - <term> - <option>-keep-hc-file</option>, - <option>-keep-hc-files</option> - <indexterm><primary><option>-keep-hc-file</option></primary></indexterm> - <indexterm><primary><option>-keep-hc-files</option></primary></indexterm> - </term> - <listitem> - <para>Keep intermediate <literal>.hc</literal> files when - doing <literal>.hs</literal>-to-<literal>.o</literal> - compilations via <link linkend="c-code-gen">C</link> (NOTE: - <literal>.hc</literal> files are only generated by - <link linkend="unreg">unregisterised</link> compilers).</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-keep-llvm-file</option>, - <option>-keep-llvm-files</option> - <indexterm><primary><option>-keep-llvm-file</option></primary></indexterm> - <indexterm><primary><option>-keep-llvm-files</option></primary></indexterm> - </term> - <listitem> - <para>Keep intermediate <literal>.ll</literal> files when - doing <literal>.hs</literal>-to-<literal>.o</literal> - compilations via <link linkend="llvm-code-gen">LLVM</link> - (NOTE: <literal>.ll</literal> files aren't generated when using the - native code generator, you may need to use <option>-fllvm</option> to - force them to be produced).</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-keep-s-file</option>, - <option>-keep-s-files</option> - <indexterm><primary><option>-keep-s-file</option></primary></indexterm> - <indexterm><primary><option>-keep-s-files</option></primary></indexterm> - </term> - <listitem> - <para>Keep intermediate <literal>.s</literal> files.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-keep-tmp-files</option> - <indexterm><primary><option>-keep-tmp-files</option></primary></indexterm> - <indexterm><primary>temporary files</primary><secondary>keeping</secondary></indexterm> - </term> - <listitem> - <para>Instructs the GHC driver not to delete any of its - temporary files, which it normally keeps in - <literal>/tmp</literal> (or possibly elsewhere; see <xref - linkend="temp-files"/>). Running GHC with - <option>-v</option> will show you what temporary files - were generated along the way.</para> - </listitem> - </varlistentry> - </variablelist> - </sect2> - - <sect2 id="temp-files"> - <title>Redirecting temporary files</title> - - <indexterm> - <primary>temporary files</primary> - <secondary>redirecting</secondary> - </indexterm> - - <variablelist> - <varlistentry> - <term> - <option>-tmpdir</option> - <indexterm><primary><option>-tmpdir</option></primary></indexterm> - </term> - <listitem> - <para>If you have trouble because of running out of space - in <filename>/tmp</filename> (or wherever your - installation thinks temporary files should go), you may - use the <option>-tmpdir - <dir></option><indexterm><primary>-tmpdir - <dir> option</primary></indexterm> option to specify - an alternate directory. For example, <option>-tmpdir - .</option> says to put temporary files in the current - working directory.</para> - - <para>Alternatively, use your <constant>TMPDIR</constant> - environment variable.<indexterm><primary>TMPDIR - environment variable</primary></indexterm> Set it to the - name of the directory where temporary files should be put. - GCC and other programs will honour the - <constant>TMPDIR</constant> variable as well.</para> - - <para>Even better idea: Set the - <constant>DEFAULT_TMPDIR</constant> make variable when - building GHC, and never worry about - <constant>TMPDIR</constant> again. (see the build - documentation).</para> - </listitem> - </varlistentry> - </variablelist> - </sect2> - - <sect2 id="hi-options"> - <title>Other options related to interface files</title> - <indexterm><primary>interface files, options</primary></indexterm> - - <variablelist> - <varlistentry> - <term> - <option>-ddump-hi</option> - <indexterm><primary><option>-ddump-hi</option></primary></indexterm> - </term> - <listitem> - <para>Dumps the new interface to standard output.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-ddump-hi-diffs</option> - <indexterm><primary><option>-ddump-hi-diffs</option></primary></indexterm> - </term> - <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 - report the differences between the old and - new <filename>.hi</filename> files.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>-ddump-minimal-imports</option> - <indexterm><primary><option>-ddump-minimal-imports</option></primary></indexterm> - </term> - <listitem> - <para>Dump to the file - <filename><replaceable>M</replaceable>.imports</filename> - (where <replaceable>M</replaceable> is the name of the - module being compiled) a "minimal" set of import - declarations. The directory where the - <filename>.imports</filename> files are created can be - controlled via the <option>-dumpdir</option> - option.</para> <para>You can safely replace all the import - declarations in - <filename><replaceable>M</replaceable>.hs</filename> with - those found in its respective <filename>.imports</filename> - file. 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> - - <varlistentry> - <term> - <option>--show-iface</option> <replaceable>file</replaceable> - <indexterm><primary><option>--show-iface</option></primary></indexterm> - </term> - <listitem> - <para>where <replaceable>file</replaceable> is the name of - an interface file, dumps the contents of that interface in - a human-readable (ish) format. See <xref linkend="modes"/>.</para> - </listitem> - </varlistentry> - </variablelist> - </sect2> - - <sect2 id="recomp"> - <title>The recompilation checker</title> - - <indexterm><primary>recompilation checker</primary></indexterm> - - <variablelist> - <varlistentry> - <term> - <option>-fforce-recomp</option> - <indexterm><primary><option>-fforce-recomp</option></primary></indexterm> - <indexterm><primary><option>-fno-force-recomp</option></primary></indexterm> - </term> - <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 module <literal>A</literal> might require module - <literal>C</literal> to be recompiled, and hence when - <filename>A.hi</filename> changes we should check whether - <literal>C</literal> should be recompiled. However, the - dependencies of <literal>C</literal> will only list - <literal>B.hi</literal>, not <literal>A.hi</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…</para> - - <para>GHC calculates a fingerprint (in fact an MD5 hash) of each - interface file, and of each declaration within the interface - file. It also keeps in every interface file a list of the - fingerprints 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 recompilation - checking is on, GHC will be clever. It compares the fingerprints - on the things it needs this time with the fingerprints - 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 early in the process saying - “Compilation IS NOT required”. What a beautiful - sight!</para> - - <para>You can read - about <ulink url="http://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/RecompilationAvoidance">how - all this works</ulink> in the GHC commentary.</para> - - </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 -> TA - f (MkTB x) = MkTA x - -module B where - import {-# SOURCE #-} A( TA(..) ) - - data TB = MkTB !Int - - g :: TA -> 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. Every loop in the module import graph must be broken by a <literal>{-# SOURCE #-}</literal> import; -or, equivalently, the module import graph must be acyclic if <literal>{-# SOURCE #-}</literal> imports are ignored. -</para> -<para>For every module <filename>A.hs</filename> that is <literal>{-# SOURCE #-}</literal>-imported -in this way there must exist a source 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 -- Produces 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 modules 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 -> Int -</programlisting> -</para></listitem> -<listitem><para> Fixity declarations are exactly as in Haskell.</para></listitem> -<listitem><para> Vanilla type synonym declarations are exactly as in Haskell.</para></listitem> -<listitem><para> Open type and data family declarations are exactly as in Haskell.</para></listitem> -<listitem><para> A closed type family may optionally omit its equations, as in the following example: -<programlisting> - type family ClosedFam a where .. -</programlisting> -The <literal>..</literal> is meant literally -- you should write two dots in your file. Note that the <literal>where</literal> clause is still necessary to distinguish closed families from open ones. If you give any equations of a closed family, you must give all of them, in the same order as they appear in the accompanying Haskell file.</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="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 :: * -> *) y -</programlisting> -You cannot use <literal>deriving</literal> on a data type declaration; write an -<literal>instance</literal> declaration instead. -</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 superclasses and class -methods entirely; but you must either omit them all or put them all in. -</para></listitem> -<listitem><para> You can include instance declarations just as in Haskell; but omit the "where" part. - </para></listitem> -<listitem><para>The default role for abstract datatype parameters is now representational. (An abstract datatype is one with no constructors listed.) To get another role, use a role annotation. (See <xref linkend="roles"/>.)</para></listitem> -</itemizedlist> -</para> - </sect2> - - <sect2 id="module-signatures"> - <title>Module signatures</title> - <para>GHC supports the specification of module signatures, which - both implementations and users can typecheck against separately. - This functionality should be considered experimental for now; some - details, especially for type classes and type families, may change. - This system was originally described in <ulink - url="http://plv.mpi-sws.org/backpack/">Backpack: Retrofitting Haskell with - Interfaces</ulink>. Signature files are somewhat similar to - <literal>hs-boot</literal> files, but have the <literal>hsig</literal> - extension and behave slightly differently. - </para> - - <para>Suppose that I have modules <filename>String.hs</filename> and - <filename>A.hs</filename>, thus:</para> - -<programlisting> -module Text where - data Text = Text String - - empty :: Text - empty = Text "" - - toString :: Text -> String - toString (Text s) = s - -module A where - import Text - z = toString empty -</programlisting> - - <para>Presently, module <literal>A</literal> depends explicitly on - a concrete implementation of <literal>Text</literal>. What if we wanted - to a signature <literal>Text</literal>, so we could vary the - implementation with other possibilities (e.g. packed UTF-8 encoded - bytestrings)? To do this, we can write a signature - <filename>TextSig.hsig</filename>, and modify <literal>A</literal> - to include the signature instead: - </para> - -<programlisting> -module TextSig where - data Text - empty :: Text - toString :: Text -> String - -module A where - import TextSig - z = toString empty -</programlisting> - - <para>To compile these two files, we need to specify what module we - would like to use to implement the signature. This can be done by - compiling the implementation, and then using the <literal>-sig-of</literal> - flag to specify the implementation backing a signature:</para> - -<programlisting> -ghc -c Text.hs -ghc -c TextSig.hsig -sig-of "TextSig is main:Text" -ghc -c A.hs -</programlisting> - - <para>To specify multiple signatures, use a comma-separated list. - The <literal>-sig-of</literal> parameter is required to specify - the backing implementations of all home modules, even in one-shot - compilation mode. - At the moment, you must specify the full module name (package key, - colon, and then module name), although in the future we may support - more user-friendly syntax.</para> - - <para>To just type-check an interface file, no <literal>-sig-of</literal> - is necessary; instead, just pass the options - <literal>-fno-code -fwrite-interface</literal>. <literal>hsig</literal> - files will generate normal interface files which other files can - also use to type-check against. However, at the moment, we always - assume that an entity defined in a signature is a unique identifier - (even though we may happen to know it is type equal with another - identifier). In the future, we will support passing shaping information - to the compiler in order to let it know about these type - equalities.</para> - - <para>Just like <literal>hs-boot</literal> files, when an - <literal>hsig</literal> file is compiled it is checked for type - consistency against the backing implementation. Signature files are also - written in a subset of Haskell essentially identical to that of - <literal>hs-boot</literal> files.</para> - - <para>There is one important gotcha with the current implementation: - currently, instances from backing implementations will "leak" code that - uses signatures, and explicit instance declarations in signatures are - forbidden. This behavior will be subject to change.</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 -f $@ - $(HC) -o $@ $(HC_OPTS) $(OBJS) - -# Standard suffix rules -.o.hi: - @: - -.lhs.o: - $(HC) -c $< $(HC_OPTS) - -.hs.o: - $(HC) -c $< $(HC_OPTS) - -.o-boot.hi-boot: - @: - -.lhs-boot.o-boot: - $(HC) -c $< $(HC_OPTS) - -.hs-boot.o-boot: - $(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 -</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 $< $(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…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 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> - - 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. These dependencies - can be generated automatically by <command>ghc</command>; see - <xref linkend="makefile-dependencies"/></para> - - </sect2> - - <sect2 id="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_pgm</command>. The command <command>ghc -M</command> will - append the needed dependencies to your - <filename>Makefile</filename>.</para> - - <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> -M.o : M.hs -</programlisting> -(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> -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> -M.o : X.hi-boot -</programlisting> - (See <xref linkend="mutual-recursion"/> for details of - <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 - <filename>makefile</filename> (or - <filename>Makefile</filename> if <filename>makefile</filename> - doesn't exist) bracketed by the lines "<literal># DO NOT - DELETE: Beginning of Haskell dependencies</literal>" and - "<literal># 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>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-pkg-deps</option> option below).</para> - - <para>The dependency generation phase of GHC can take some - additional options, which you may find useful. - - The options which affect dependency generation are:</para> - - <variablelist> - <varlistentry> - <term><option>-ddump-mod-cycles</option></term> - <listitem> - <para>Display a list of the cycles in the module graph. This is - useful when trying to eliminate such cycles.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-v2</option></term> - <listitem> - <para>Print a full list of the module dependencies 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>-dep-makefile</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>-dep-makefile .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>-dep-suffix <suf></option></term> - <listitem> - <para>Make extra dependencies that declare that files - with suffix - <filename>.<suf>_<osuf></filename> - depend on interface files with suffix - <filename>.<suf>_hi</filename>, or (for - <literal>{-# SOURCE #-}</literal> - imports) on <filename>.hi-boot</filename>. Multiple - <option>-dep-suffix</option> flags are permitted. For example, - <option>-dep-suffix a -dep-suffix b</option> - will make dependencies - for <filename>.hs</filename> on - <filename>.hi</filename>, - <filename>.a_hs</filename> on - <filename>.a_hi</filename>, and - <filename>.b_hs</filename> on - <filename>.b_hi</filename>. (Useful in - conjunction with NoFib "ways".)</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>--exclude-module=<file></option></term> - <listitem> - <para>Regard <filename><file></filename> as - "stable"; i.e., exclude it from having dependencies on - it.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-include-pkg-deps</option></term> - <listitem> - <para>Regard modules imported from packages as unstable, - i.e., generate dependencies on any imported package modules - (including <literal>Prelude</literal>, and all other - 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> - - </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 <emphasis>head</emphasis> of the instance declaration -(the part after the “<literal>=></literal>”; see <xref linkend="instance-rules"/>), 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”. -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> -Functional dependencies complicate matters. Suppose we have: -<programlisting> - module B where - instance E T Int where ... - data T = ... -</programlisting> -Is this an orphan module? Apparently not, because <literal>T</literal> -is declared in the same module. But suppose class <literal>E</literal> had a -functional dependency: -<programlisting> - module Lib where - class E x y | y -> x where ... -</programlisting> -Then in some importing module M, the constraint <literal>(E a Int)</literal> should be "improved" by setting -<literal>a = T</literal>, <emphasis>even though there is no explicit mention -of <literal>T</literal> in M</emphasis>.</para> - -These considerations lead to the following definition of an orphan module: -<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> -<itemizedlist> -<listitem><para> - The class of the instance declaration is not declared in M, and -</para></listitem> -<listitem> -<para> <emphasis>Either</emphasis> the class has no functional dependencies, and none of the type constructors - in the instance head is declared in M; <emphasis>or</emphasis> there - is a functional dependency for which none of the type constructors mentioned - in the <emphasis>non-determined</emphasis> part of the instance head is defined in M. - </para></listitem> - </itemizedlist> - </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>If you use the flag <option>-fwarn-orphans</option>, GHC will warn you -if you are creating an orphan module. -Like any warning, you can switch the warning off with <option>-fno-warn-orphans</option>, -and <option>-Werror</option> -will make the compilation fail if the warning is issued. -</para> -<para> -You can identify an orphan module by looking in its interface -file, <filename>M.hi</filename>, using the -<link linkend="modes"><option>--show-iface</option> mode</link>. If there is a <literal>[orphan module]</literal> on the -first line, GHC considers it an orphan module. -</para> -</sect2> - - </sect1> - -<!-- Emacs stuff: - ;;; Local Variables: *** - ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter" "sect1") *** - ;;; ispell-local-dictionary: "british" *** - ;;; End: *** - --> |