
In trying to test my LLVM-dynamic linking changes, I've encountered some builds which fail with, Bad interface file: dist-install/build/GHC/CString.hi mismatched interface file ways (wanted "dyn", got "") during `make install`. The failing command is `ghc-stage2`, invoked by `ghc-cabal`, ../../inplace/bin/ghc-stage2 '-B/opt/exp/ghc/root-ghc-7.8-dyn/lib/ghc-7.7.20131221' '--abi-hash' '-fbuilding-cabal-package' '-O' '-outputdir' 'dist-install/build' '-odir' 'dist-install/build' '-hidir' 'dist-install/build' '-stubdir' 'dist-install/build' '-i' '-idist-install/build' '-i.' '-idist-install/build/autogen' '-Idist-install/build/autogen' '-Idist-install/build' '-optP-include' '-optPdist-install/build/autogen/cabal_macros.h' '-package-name' 'ghc-prim-0.3.1.0' '-hide-all-packages' '-no-user-package-db' '-package-id' 'builtin_rts' '-XHaskell2010' 'GHC.CString' 'GHC.Classes' 'GHC.Debug' 'GHC.IntWord64' 'GHC.Magic' 'GHC.PrimopWrappers' 'GHC.Tuple' 'GHC.Types' 'GHC.Prim' '-package-name' 'ghc-prim' The build is on an x86_64 box with `build.mk` containing, GhcDebugged = YES DYNAMIC_BY_DEFAULT = YES # Roughly BuildFlavour=quick-llvm without disabling dynamic linking SRC_HC_OPTS = -H64m -O0 -fllvm # -keep-llvm-files GhcStage1HcOpts = -O -fllvm GhcStage2HcOpts = -O0 -fllvm GhcLibHcOpts = -O -fllvm SplitObjs = NO HADDOCK_DOCS = NO BUILD_DOCBOOK_HTML = NO BUILD_DOCBOOK_PS = NO BUILD_DOCBOOK_PDF = NO I've spent the morning tracing through the interface loading code and have finally met an impasse. As far as I can tell, the relevant subset of the call graph is, LoadIface.lhs: loadInterface LoadIface.lhs : findAndReadIface Finder.hs: findExactModule Finder.hs: findHomeModule Finder.hs: homeSearchCache Finder.hs: findHomeModule findAndReadIface(read_file) findAndReadIface(checkBuildDynamicToo) whenGeneratingDynamicToo TcRnMonad.hs: withDoDynamicToo DynFlags.hs: dynamicTooMkDynamicDynFlags findAndReadIface(read_file) where findAndReadIFace(read_file) LoadIface.lhs : readIface BinIface.hs : readBinIface Up until `checkBuildDynamicToo` the dynflags have, ways dflags == [WayDyn] buildTag dflags == "dyn" hiSuf dflags == "hi" dynHiSuf dflags == "dyn_hi" Given this, it's perhaps unsurprising that `readBinIface` gets quite confused when it attempts to read `dist-install/build/GHC/CString.hi` to find that it was compiled with a null tag, not `dyn` as expected. If I add `-static` to the command line the build succeeds. However, adding `-dynamic` or `-dynamic-too` or omitting all of the above (due to `DYNAMIC_BY_DEFAULT`) all fail. It seems that `findAndReadIface` attempts to account for `-dynamic-too` but I don't see how the approach should work: it tries to first load the static interface file (but with `ways==[WayDyn]`) then tries again to load the interface using `DynFlags` and .hi file name constructed for the dynamic case. I can't see how this would ever work as `readBinIface` will expect to see a dynamic interface file due to the DynFlags' ways. It's also unclear how the `-dynamic` case (not `-dynamic-too`) is handled under this scheme. I would have thought that running with `-dynamic` would cause `hiSuf == dynHiSuf` but I can't find any code to suggest this is the case. Could someone offer some insight into how interface loading, `-dynamic`, and `-dynamic-too` are supposed to interact? Thanks, - Ben