GHC not generating dyn_hi files
Overview
In dynamic-too compilation, a module is compiled the normal way, then the backend runs twice to generate normal (.o, .hi) and dynamic (.dyn_o, .dyn_hi) outputs. Compilation uses the .hi files of imported modules. Effectively, the compiler assumes that all the information it gets from a .hi file, used by the normal output, is also true of the corresponding .dyn_hi file, used by the dynamic output. GHC has a few checks to verify this, but they don’t always produce desirable results.
- When importing a module from a package in --make mode, GHC checks that the normal and dynamic interfaces match, in
checkBuildDynamicToo
infindAndReadIface
. If they don’t match, GHC silently disables dynamic-too, so that no dynamic interface file is produced. No errors or warnings are reported. - When importing a module (either from a package, or standalone) in one-shot mode with -c, GHC starts out the same way as above: it checks the imported interfaces, finds out they don't match, and disables dynamic-too output. After generating output the normal way, the compiler pipeline runs again in the dynamic way to generate the dynamic output. This seems to be the "right" thing to do.
- When importing a standalone module in --make mode, GHC does not examine the dynamic interface at all. It generates both normal and dynamic output.
Of the two --make cases, GHC uses the weaker checks when building a package and stricter checks when using the installed package. The weaker checks allow a package with mismatched normal and dynamic interface files to build and install without errors. After it's installed, the stronger checks suppress the creation of .dyn_hi files whenever the mismatched module is imported. Thus, a package installs fine, but importing from the package prevents dynamic-too compilation from working properly.
Reproducing
The attached code sets up an inconsistent pair of module interfaces and runs both kinds of imports. To compile the first two files, build the cabal package in testcase9176/
. To compile the last file, install the package, then run the makefile in user/
.
-
Imported.hs
is compiled with different optimization flags, setting up a situation where the normal and dyamic module interfaces do not match. -
User.hs
importing directlyImported.hs
loads only the static module interface. The dynamic interface is ignored. -
User.hs
importing from the installed packageImported.hs
compares the static and dynamic interfaces, turns off dynamic-too compilation, and does not generate a .dyn_hi file. No errors or warnings are produced. This file is a copy of the otherUser.hs
, just compiled differently.
Problems
GHC with -dynamic-too is expected to generate a .dyn_hi file, but it does not when compiling the third file.
When compiling a module, GHC should read the interfaces of any modules that it imports. However, when compiling the second file, GHC does not read the .dyn_hi file describing the imported dynamic module, only the .hi file describing the normal module.
The compiler does not treat mismatched module interfaces consistently in all situations, making it hard to find the root cause of errors.
I'm not sure what the correct behavior should be.
Details
This bug appeared on my system in a Parsec module. Parsec installed with no apparent problems, but other modules importing from Parsec would not compile to .dyn_hi files.
GHC was built from source, commit 9e10963e, compiled by GHC 7.6.3 with XCode 5.1.1 on OS X 10.9.3.