X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fseparate_compilation.xml;h=32dc850e3cee88f5c69521c609419a6d1898c931;hb=4ca6790feb128b03e0783de7f44399fef5c5ad22;hp=696d6878697e0b67fb3fb21731bfc8218351ef09;hpb=dfcf88523ec5988fbcaa2cbf812cc5862ad621cf;p=ghc-hetmet.git diff --git a/docs/users_guide/separate_compilation.xml b/docs/users_guide/separate_compilation.xml index 696d687..32dc850 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. @@ -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 @@ -434,7 +450,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` + , + @@ -449,7 +467,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` + , + @@ -459,7 +479,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` + , + @@ -557,9 +579,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 +609,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 +625,9 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` - - - + + + Turn off recompilation checking (which is on by @@ -639,24 +661,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. @@ -694,8 +716,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 +729,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 @@ -770,7 +795,7 @@ When a hs-boot file A.hs-boot 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. @@ -810,13 +835,13 @@ can be given abstractly, by omitting the '=' sign and everything that follows. 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 + 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 in +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 @@ -913,11 +938,11 @@ Foo.o Foo.hc Foo.s : Baz.hi # Foo imports Baz 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 - + - + Dependency generation dependencies in Makefiles Makefile dependencies @@ -1000,30 +1025,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 ; @@ -1032,14 +1050,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 @@ -1047,21 +1065,8 @@ ghc -M -optdep-f -optdep.depend ... - - - + Make extra dependencies that declare that files with suffix @@ -1070,13 +1075,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".) @@ -1092,33 +1098,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, @@ -1147,7 +1126,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 @@ -1165,8 +1145,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 @@ -1174,12 +1177,21 @@ defined thus: least one orphan rule. 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 + orphan instance + + + 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. @@ -1191,17 +1203,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.