Reputation: 21811
My project uses FFI, so I always have to link against precompiled object files testing with GHCi:
ghci Foo a.o
My question is: Is there a way to do this once GHCi is running instead of GHCi startup? I've tried this:
$ ghci
> :l Foo a.o
but I get the error a.o is not a module name or a source file
My goal for this is to be able to start a GHCi session with external symbols linked in via a .ghci
file. My motivation is that cabal compiles the object files into dist/build/my-tests/my-tests-tmp/src/../../../../a.o
, which ends up being 92 characters long. It's bad enough to have to type this once (with a *,o
at the end), but due to a regression in GHC 7.8, I have to link five object files in a specific order which requires over 500 characters after ghci Foo
.
** UPDATE **
The following example demonstrates why n.m.'s solution below isn't working for me on GHC 7.8.2:
mul.c
#include <inttypes.h>
void mulRq (int64_t* a, int64_t* b, int32_t totm, int64_t q) { }
Mul.hs
module Mul where
import Data.Int
import Foreign.Ptr
foreign import ccall unsafe "mulRq" mulRq ::
Ptr Int64 -> Ptr Int64 -> Int64 -> Int64 -> IO ()
Dummy.hs is empty.
Steps:
ghci Mul
[can't find label mulRq]
ghci Mul mul.o
[ghci loads]
ghci Dummy
[ghci loads without compiling]
ghci Dummy
[ghci loads without compiling]
nm Dummy.o
[verify that Dummy.o contains the symbol mulRq]
Now start ghci:
$ ghci
GHCi, version 7.8.2:
...
Prelude> :l Dummy
Ok, modules loaded: Main.
Prelude Main> :l Mul
[1 of 1] Compiling Mul ( Mul.hs, interpreted )
ByteCodeLink: can't find label
During interactive linking, GHCi couldn't find the following symbol:
mulRq
Upvotes: 2
Views: 979
Reputation: 120049
Dummy.hs
into Dummy.o
. It can be totally empty, or contain any useful Haskell code.ghci Dummy
loads an existing compiled version of Dummy
(does not print Compiling
when loading it).Combine Dummy.o
and a.o
:
ld -r Dummy.o a.o -o temp.o
mv temp.o Dummy.o
Now you have a loadable Haskell module Dummy
that also contains all of the a.o
.
Update
This scheme works if modules that use a.o/Dummy.o
are compiled to object code, and does not work if they are interpreted.
A simple way to always use compiled code is to run GHCi with -fobject-code
. Using your example,
ghci -fobject-code
Prelude> :l Dummy
Ok, modules loaded: Dummy.
Prelude Dummy> :l Mul
[1 of 1] Compiling Mul ( Mul.hs, Mul.o )
Ok, modules loaded: Mul.
Prelude Mul>
Upvotes: 1