interaction of all the other pieces that make up GHC. It supersedes the
<em>Evil Driver (ED),</em> which was a Perl script that served the same
purpose and was in use until version 4.08.1 of GHC. Simon Marlow
- eventually slayed the ED and instated the GD.
+ eventually slayed the ED and instated the GD. The GD is usually called
+ the <em>Compilation Manager</em> these days.
</p>
<p>
The GD has been substantially extended for GHCi, i.e., the interactive
variant of GHC that integrates the compiler with a (meta-circular)
- interpreter since version 5.00.
+ interpreter since version 5.00. Most of the driver is located in the
+ directory
+ <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/main/"><code>fptools/ghc/compiler/main/</code></a>.
</p>
+ <h2>Command Line Options</h2>
+ <p>
+ GHC's many flavours of command line options make the code interpreting
+ them rather involved. The following provides a brief overview of the
+ processing of these options. Since the addition of the interactive
+ front-end to GHC, there are two kinds of options: <em>static
+ options</em> and <em>dynamic options.</em> The former can only be set
+ when the system is invoked, whereas the latter can be altered in the
+ course of an interactive session. A brief explanation on the difference
+ between these options and related matters is at the start of the module
+ <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/main/CmdLineOpts.lhs"><code>CmdLineOpts</code></a>.
+ The same module defines the enumeration <code>DynFlag</code>, which
+ contains all dynamic flags. Moreover, there is the labelled record
+ <code>DynFlags</code> that collects all the flag-related information
+ that is passed by the compilation manager to the compiler proper,
+ <code>hsc</code>, whenever a compilation is triggered. If you like to
+ find out whether an option is static, use the predicate
+ <code>isStaticHscFlag</code> in the same module.
+ <p>
+ The second module that contains a lot of code related to the management
+ of flags is <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/main/DriverFlags.hs"><code>DriverFlags.hs</code></a>.
+ In particular, the module contains two association lists that map the
+ textual representation of the various flags to a data structure that
+ tells the driver how to parse the flag (e.g., whether it has any
+ arguments) and provides its internal representation. All static flags
+ are contained in <code>static_flags</code>. A whole range of
+ <code>-f</code> flags can be negated by adding a <code>-f-no-</code>
+ prefix. These flags are contained in the association list
+ <code>fFlags</code>.
+ <p>
+ The driver uses a nasty hack based on <code>IORef</code>s that permits
+ the rest of the compiler to access static flags as CAFs; i.e., there is
+ a family of toplevel variable definitions in
+ <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/main/CmdLineOpts.lhs"><code>CmdLineOpts</code></a>,
+ below the literate section heading <i>Static options</i>, each of which
+ contains the value of one static option. This is essentially realised
+ via global variables (in the sense of C-style, updatable, global
+ variables) defined via an evil pre-processor macro named
+ <code>GLOBAL_VAR</code>, which is defined in a particularly ugly corner
+ of GHC, namely the C header file
+ <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/HsVersions.h"><code>HsVersions.h</code></a>.
+
<h2>Linking the <code>RTS</code> and <code>libHSstd</code></h2>
<p>
Since the RTS and HSstd refer to each other, there is a Cunning
Hack to avoid putting them each on the command-line twice or
thrice (aside: try asking for `plaice and chips thrice' in a
- fish and chip shop; bet you only get two lots), namely to add
+ fish and chip shop; bet you only get two lots). The hack involves
+ adding
the symbols that the RTS needs from libHSstd, such as
<code>PrelWeak_runFinalizzerBatch_closure</code> and
- <code>__init_Prelude</code> to the link line with the
- <code>-u</code> flag. The standard library appears before the
- RTS on the link line (why? might it be better the other way
- around? [SPJ]), and these options cause the corresponding
- symbols to be picked up even if they haven't been already, so
- that when the RTS is also scanned, they are resolved. This
+ <code>__init_Prelude</code>, to the link line with the
+ <code>-u</code> flag. The standard library appears before the
+ RTS on the link line, and these options cause the corresponding
+ symbols to be picked up even so the linked might not have seen them
+ being used as the RTS appears later on the link line. As a result,
+ when the RTS is also scanned, these symbols are already resolved. This
avoids the linker having to read the standard library and RTS
multiple times.
</p>
<p>
- This does, however, lead to a complication. Normal Haskell
- programs do not have a <code>main</code> function, so this is
- supplied by the RTS. It calls <code>startupHaskell</code>, which
+ This does, however, leads to a complication. Normal Haskell
+ programs do not have a <code>main()</code> function, so this is
+ supplied by the RTS (in the file
+ <a href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/rts/Main.c"><code>Main.c</code></a>).
+ It calls <code>startupHaskell</code>, which
itself calls <code>__init_PrelMain</code>, which is therefore,
since it occurs in the standard library, one of the symbols
- passed to the linker. However, when the <code>main</code>
- function is provided by the programmer (e.g. when there is no
- main module, but a C module instead),
+ passed to the linker using the <code>-u</code> option. This is fine
+ for standalone Haskell programs, but as soon as the Haskell code is only
+ used as part of a program implemented in a foreign language, the
+ <code>main()</code> function of that foreign language should be used
+ instead of that of the Haskell runtime. In this case, the previously
+ described arrangement unfortunately fails as
<code>__init_PrelMain</code> had better not be linked in,
because it tries to call <code>__init_Main</code>, which won't
- exist. This case is coped with by the <code>-no-hs-main</code>
- flag, although in some versions of the compiler (e.g. 5.00.2) it
- didn't work.
+ exist. In other words, the RTS's <code>main()</code> refers to
+ <code>__init_PrelMain</code> which in turn refers to
+ <code>__init_Main</code>. Although the RTS's <code>main()</code>
+ might not be linked in if the program provides its own, the driver
+ will normally force <code>__init_PrelMain</code> to be linked in anyway,
+ using <code>-u</code>, because it's a back-reference from the
+ RTS to HSstd. This case is coped with by the <code>-no-hs-main</code>
+ flag, which suppresses passing the corresonding <code>-u</code> option
+ to the linker -- although in some versions of the compiler (e.g., 5.00.2)
+ it didn't work. In addition, the driver arranges that the C program
+ providing the <code>main()</code> that we want to use appears in the
+ link line after the RTS. Therefore, the RTS's main is never used and
+ without the <code>-u</code> the label <code>__init_PrelMain</code>
+ will not be linked.
</p>
<p><small>
<!-- hhmts start -->
-Last modified: Wed Aug 22 17:01:33 GMT Daylight Time 2001
+Last modified: Fri Aug 24 16:16:10 EST 2001
<!-- hhmts end -->
</small>
</body>