X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fseparate_compilation.xml;h=e2c9c33b4c23a8eef34f14fe062561fd6329648f;hb=2c8aabcad1d2f2c469cb8a10afa7b66beeaedd45;hp=c33ff2175b6935222206bdb4b5e0b3f6f3aefc1c;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/docs/users_guide/separate_compilation.xml b/docs/users_guide/separate_compilation.xml index c33ff21..e2c9c33 100644 --- a/docs/users_guide/separate_compilation.xml +++ b/docs/users_guide/separate_compilation.xml @@ -114,7 +114,9 @@ has been specified, then the object filename is dir/mod.osuf, where mod is the module name with - dots replaced by slashes. + dots replaced by slashes. GHC will silently create the necessary directory + structure underneath dir, if it does not + already exist. @@ -182,7 +184,7 @@ dots replaced by the directory separator ('/' or '\', depending on the system), and extension is a source extension (hs, lhs) - if we are in mode and GHCi, or + if we are in mode or GHCi, or hisuf otherwise. For example, suppose the search path contains directories @@ -218,7 +220,7 @@ This isn't the whole story: GHC also looks for modules in pre-compiled libraries, known as packages. See the section on - packages (), for details. + packages () for details. @@ -271,7 +273,7 @@ If you use ghc --make and you don't use the , the name GHC will choose for the executable will be based on the name of the file - containing the module Main. + containing the module Main. Note that with GHC the Main module doesn't have to be put in file Main.hs. Thus both @@ -297,7 +299,7 @@ dir. For example: -$ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` +$ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `uname -m` The object files, Foo.o, @@ -372,6 +374,20 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` + + + dir + + + + The option is shorthand for + the combination + of , , + and . + + + + suffix @@ -417,13 +433,15 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` - + Keeping Intermediate Files intermediate files, saving .hc files, saving + .ll files, saving + .s files, saving @@ -434,40 +452,45 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` + , + Keep intermediate .hc files when doing .hs-to-.o compilations via C (NOTE: .hc files - aren't generated when using the native code generator, you - may need to use to force them - to be produced). + are only generated by unregisterised compilers). - - + , + + + - Keep intermediate .s files. + Keep intermediate .ll files when + doing .hs-to-.o + compilations via LLVM (NOTE: .ll files + aren't generated when using the native code generator, you + may need to use to force them + to be produced). - - + , + + + - Keep intermediate .raw-s files. - These are the direct output from the C compiler, before - GHC does “assembly mangling” to produce the - .s file. Again, these are not produced - when using the native code generator. + Keep intermediate .s files. @@ -557,9 +580,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` the same as the old one; this is friendly to make. When an interface does change, it is often enlightening to be informed. The - option will make GHC run - diff on the old and new - .hi files. + option will make GHC + report the differences between the old and + new .hi files. @@ -587,9 +610,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` - Where file is the name of + where file is the name of an interface file, dumps the contents of that interface in - a human-readable (ish) format. + a human-readable (ish) format. See . @@ -603,9 +626,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` - - - + + + Turn off recompilation checking (which is on by @@ -639,24 +662,24 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` B, say) may conceivably not change B.hi one jot. So now… - 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 the recompilation 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 “Compilation IS NOT - required”. What a beautiful sight! - - Patrick Sansom had a workshop paper about how all this is - done (though the details have changed quite a bit). Ask him if you want a - copy. + 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 .o 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! + + You can read + about how + all this works in the GHC commentary. @@ -670,22 +693,22 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` This section explains how. Every cycle in the module import graph must be broken by a hs-boot file. - Suppose that modules A.hs and B.hs are Haskell source files, + Suppose that modules A.hs and B.hs are Haskell source files, thus: 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 @@ -694,8 +717,11 @@ module B where hi-boot files Here A imports B, but B imports A with a {-# SOURCE #-} pragma, which breaks the -circular dependency. For every module A.hs that is {-# SOURCE #-}-imported -in this way there must exist a souce file A.hs-boot. This file contains an abbreviated +circular dependency. Every loop in the module import graph must be broken by a {-# SOURCE #-} import; +or, equivalently, the module import graph must be acyclic if {-# SOURCE #-} imports are ignored. + +For every module A.hs that is {-# SOURCE #-}-imported +in this way there must exist a source file A.hs-boot. This file contains an abbreviated version of A.hs, thus: module A where @@ -704,7 +730,7 @@ module A where To compile these three files, issue the following commands: - ghc -c A.hs-boot -- Poduces A.hi-boot, A.o-boot + 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 @@ -724,12 +750,12 @@ module A where ghc -c A.hs-boot -When a hs-boot file A.hs-boot +When a hs-boot file A.hs-boot is compiled, it is checked for scope and type errors. When its parent module A.hs is compiled, the two are compared, and an error is reported if the two are inconsistent. - + Just as compiling A.hs produces an interface file A.hi, and an object file @@ -767,10 +793,10 @@ When a hs-boot file A.hs-boot ghc -M will report an error if a cycle is found. - A module M that is + A module M that is {-# SOURCE #-}-imported in a program will usually also be ordinarily imported elsewhere. If not, ghc --make - automatically adds M to the set of moudles it tries to + automatically adds M to the set of modules it tries to compile and link, to ensure that M's implementation is included in the final program. @@ -786,9 +812,9 @@ A hs-boot file need only contain the bare A hs-boot file is written in a subset of Haskell: The module header (including the export list), and import statements, are exactly as in -Haskell, and so are the scoping rules. +Haskell, and so are the scoping rules. Hence, to mention a non-Prelude type or class, you must import it. - + There must be no value declarations, but there can be type signatures for values. For example: @@ -797,7 +823,7 @@ values. For example: Fixity declarations are exactly as in Haskell. Type synonym declarations are exactly as in Haskell. - A data type declaration can either be given in full, exactly as in Haskell, or it + 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: data T a b @@ -809,19 +835,21 @@ can be given abstractly, by omitting the '=' sign and everything that follows. You can also write out the constructors but, if you do so, you must write it out precisely as in its real definition. - If you do not write out the constructors, you may need to give a kind - annotation (), to tell + If you do not write out the constructors, you may need to give a kind + annotation (), 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: data R (x :: * -> *) y +You cannot use deriving on a data type declaration; write an +instance declaration instead. Class declarations is exactly as in Haskell, except that you may not put -default method declarations. You can also omit all the class methods entirely. +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. - Do not include instance declarations. There is a complication to do with -how the dictionary functions are named. It may well work, but it's not a well-tested feature. + You can include instance declarations just as in Haskell; but omit the "where" part. @@ -910,12 +938,12 @@ Foo.o Foo.hc Foo.s : Baz.hi # Foo imports Baz 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. These dependencies - can be generated automatically by ghc; see - + can be generated automatically by ghc; see + - + Dependency generation dependencies in Makefiles Makefile dependencies @@ -939,7 +967,7 @@ depend : Makefile. In general, ghc -M Foo does the following. - For each module M in the set + For each module M in the set Foo plus all its imports (transitively), it adds to the Makefile: @@ -962,7 +990,7 @@ M.o : X.hi-boot (See for details of hi-boot style interface files.) - + If M imports multiple modules, then there will be multiple lines with M.o as the target. @@ -998,30 +1026,23 @@ M.o : X.hi-boot option below). 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 - -optdep. For example, to pass -f - .depend to the dependency generator, you say - - -ghc -M -optdep-f -optdep.depend ... - + additional options, which you may find useful. The options which affect dependency generation are: - + - Turn off warnings about interface file shadowing. + Display a list of the cycles in the module graph. This is + useful when trying to eliminate such cycles. - Print a full list of the module depenencies to stdout. + Print a full list of the module dependencies to stdout. (This is the standard verbosity flag, so the list will also be displayed with and ; @@ -1030,14 +1051,14 @@ ghc -M -optdep-f -optdep.depend ... - file + file Use file as the makefile, rather than makefile or Makefile. If file doesn't exist, mkdependHS creates it. We often use - to put the dependencies in + to put the dependencies in .depend and then include the file .depend into @@ -1045,21 +1066,8 @@ ghc -M -optdep-f -optdep.depend ... - - + Make extra dependencies that declare that files with suffix @@ -1068,13 +1076,14 @@ ghc -M -optdep-f -optdep.depend ... .<suf>_hi, or (for {-# SOURCE #-} imports) on .hi-boot. Multiple - flags are permitted. For example, - will make dependencies - for .hc on + flags are permitted. For example, + + will make dependencies + for .hs on .hi, - .a_hc on + .a_hs on .a_hi, and - .b_hc on + .b_hs on .b_hi. (Useful in conjunction with NoFib "ways".) @@ -1090,33 +1099,6 @@ ghc -M -optdep-f -optdep.depend ... - - - same as - - - - - - - Regard the colon-separated list of directories - <dirs> as containing stable, - don't generate any dependencies on modules - therein. - - - - - - - Regard <file> as not - "stable"; i.e., generate dependencies on it (if - any). This option is normally used in conjunction with - the option. - - - - Regard modules imported from packages as unstable, @@ -1145,7 +1127,8 @@ 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. In particular, if an instance declaration is in the same module as the definition -of any type or class mentioned in the head of the instance declaration, then +of any type or class mentioned in the head of the instance declaration +(the part after the “=>”; see ), then GHC has to visit that interface file anyway. Example: module A where @@ -1163,8 +1146,31 @@ and GHC has no other reason for visiting the module. Example: class C a where ... Here, neither D nor T is declared in module Orphan. -We call such modules ``orphan modules'', -defined thus: +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. + + +Functional dependencies complicate matters. Suppose we have: + + module B where + instance E T Int where ... + data T = ... + +Is this an orphan module? Apparently not, because T +is declared in the same module. But suppose class E had a +functional dependency: + + module Lib where + class E x y | y -> x where ... + +Then in some importing module M, the constraint (E a Int) should be "improved" by setting +a = T, even though there is no explicit mention +of T in M. + +These considerations lead to the following definition of an orphan module: An orphan module orphan module @@ -1173,11 +1179,20 @@ defined thus: An instance declaration in a module M is an orphan instance if orphan instance - none of the type constructors - or classes mentioned in the instance head (the part after the ``=>'') are declared - in M. - - Only the instance head counts. In the example above, it is not good enough for C's declaration + + + The class of the instance declaration is not declared in M, and + + + Either the class has no functional dependencies, and none of the type constructors + in the instance head is declared in M; or there + is a functional dependency for which none of the type constructors mentioned + in the non-determined part of the instance head is defined in M. + + + + 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. @@ -1189,17 +1204,18 @@ defined thus: - 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. +If you use the flag , GHC will warn you +if you are creating an orphan module. +Like any warning, you can switch the warning off with , +and +will make the compilation fail if the warning is issued. - - You can identify an orphan module by looking in its interface + +You can identify an orphan module by looking in its interface file, M.hi, using the -. If there is a ``!'' on the first line, -GHC considers it an orphan module. + mode. If there is a [orphan module] on the +first line, GHC considers it an orphan module. @@ -1207,7 +1223,6 @@ GHC considers it an orphan module.