Joe
Joe

Reputation: 1564

Haskell GHCI not loading compiled object file

I would like GHCI to load the compiled object code for a module which when compiled is significantly faster than the none compiled version. This was working well when all of the files were in the same directory (no module hierarchies). However, they do not work when the files are in module hierarchies.

Working version MyFile.hs:

import Basic
import Histogram

where Basic.o and Histogram.o are in the same directory as MyFile.hs

Not Working version MyFile.hs:

import Util.Basic
import Util.Histogram

where Basic.o and Histogram.o are in a subdirectory Util. With this version I get the following when loading MyFile.hs:

[1 of 2] Compiling Util.Basic ( Util/Basic.hs, interpreted )
[2 of 2] Compiling Util.Histogram ( Util/Histogram.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram.

I would like to be able to organize my code in modules but still receive the benefits from using the compiled o files.

Also, it should be noted that the source files have not been changed since the o files were compiled.

Edits: Here are the contents of each file:

MyFile.hs

import Util.Basic
import Util.Histogram

Util/Basic.hs

module Util.Basic () where

Util/Histogram.hs

module Util.Histogram () where

Files / Compilation:

$:~/programming/haskell/example-error$ ls
MyFile.hs  MyFile.hs~  Util
$:~/programming/haskell/example-error$ cd Util
$:~/programming/haskell/example-error/Util$ ls
Basic.hs  Basic.hs~  Histogram.hs  Histogram.hs~
$:~/programming/haskell/example-error/Util$ ghc *.hs
[1 of 2] Compiling Util.Histogram   ( Histogram.hs, Histogram.o )
[2 of 2] Compiling Util.Basic       ( Basic.hs, Basic.o )
$:~/programming/haskell/example-error/Util$ ls
Basic.hi  Basic.hs~  Histogram.hi  Histogram.hs~
Basic.hs  Basic.o    Histogram.hs  Histogram.o
$:~/programming/haskell/example-error/Util$  cd ../
$:~/programming/haskell/example-error$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 3] Compiling Util.Histogram   ( Util/Histogram.hs, interpreted )
[2 of 3] Compiling Util.Basic       ( Util/Basic.hs, interpreted )
[3 of 3] Compiling Main             ( MyFile.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram, Main.
*Main> 

The Solution that worked as suggested by Daniel:

The fix is to compile the importing file, and the files in the 
subdirectory only as a consequence of that, not directly. 

Upvotes: 3

Views: 1398

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183978

The issue is the same as discussed below, the flags changed:

~/.../Util> ghc Other.hs
[1 of 1] Compiling Util.Other       ( Other.hs, Other.o )
~/.../Util> cd ..
~/.../src> ghc MyFile.hs
[1 of 2] Compiling Util.Other       ( Util/Other.hs, Util/Other.o ) [flags changed]
[2 of 2] Compiling MyFile           ( MyFile.hs, MyFile.o )

I haven't found out which flags in particular, or why the flags passed during separate compilation are different than the ones that are passed when compiling as a module chased from the importing module, but they do change, and hence a recompilation is necessary (Specifically, the flag-hash value in the .hi file changes).

The fix is therefore to not compile the modules separately, but to compile them as dependencies of the top-level importer.


Original almost correct guesswork:

I can only partly reproduce that. After compiling and then touching MyFile.hs,

$ ghci-7.4.2 MyFile.hs
-- snip
[1 of 2] Compiling Util.Other       ( Util/Other.hs, interpreted )
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

it looks the same as for you, but with 7.6.1, we get a hint (compiling and touching):

$ ghci MyFile.hs
-- snip
[1 of 2] Compiling Util.Other       ( Util/Other.hs, interpreted ) [flags changed]
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

The flags changed. I have :set -XNoMonomorphismRestriction in my .ghci file, and the change of flags causes the recompilation.

$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

Ignoring the offending .ghci with the flag that wasn't given for the compilation, the unchanged Util.Other is not interpreted, the compiled code is used. (With GHC < 7.4, ignoring the .ghci file isn't even necessary.)

If you have a .ghci file in which you set language options (NoMonomorphismRestriction, TypeFamilies, ...) and ghc >= 7.4, you need to ignore the .ghci file when loading the modules.

If that is not the case, the recompilation is not the expected behaviour. Then more information would be necessary to diagnose the problem and find a fix.

A semi-work-around would then be the -fobject-code flag for ghci.

Upvotes: 5

Related Questions