我的项目使用FFI,所以我总是要链接到使用GHCi进行测试的预编译对象文件:
ghci Foo a.o
我的问题是:一旦GHCi正在运行而不是GHCi启动,有没有办法做到这一点? 我试过这个:
$ ghci
> :l Foo a.o
但我收到错误a.o is not a module name or a source file
我的目标是能够启动 GHCi会话,其中包含通过.ghci
文件链接的外部符号。我的动机是cabal将目标文件编译成dist/build/my-tests/my-tests-tmp/src/../../../../a.o
,最终长度为92个字符。这一次打字很糟糕(最后用*,o
),但是由于regression in GHC 7.8,我必须按照特定的顺序链接五个目标文件,这需要超过500个字符{ {1}}。
**更新**
以下示例说明了为什么n.m.的解决方案在GHC 7.8.2上对我不起作用:
mul.c
ghci Foo
Mul.hs
#include <inttypes.h>
void mulRq (int64_t* a, int64_t* b, int32_t totm, int64_t q) { }
Dummy.hs是空的。
步骤:
ghci Mul
[找不到标签mulRq]
ghci Mul mul.o
[ghci loads]
ghci Dummy
[ghci加载没有编译]
ghci Dummy
[ghci加载没有编译]
nm Dummy.o
[验证Dummy.o包含符号mulRq]
现在开始ghci:
module Mul where
import Data.Int
import Foreign.Ptr
foreign import ccall unsafe "mulRq" mulRq ::
Ptr Int64 -> Ptr Int64 -> Int64 -> Int64 -> IO ()
答案 0 :(得分:1)
Dummy.hs
编译为Dummy.o
。它可以是完全空的,或包含任何有用的Haskell代码。ghci Dummy
加载Dummy
的现有编译版本(加载时不会打印Compiling
)。合并Dummy.o
和a.o
:
ld -r Dummy.o a.o -o temp.o
mv temp.o Dummy.o
现在您有一个可加载的Haskell模块Dummy
,它还包含所有a.o
。
<强>更新强>
如果将使用 a.o/Dummy.o
的模块编译为目标代码,并且在解释它们时不起作用,则此方案有效。
始终使用已编译代码的一种简单方法是使用-fobject-code
运行GHCi。使用您的示例,
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>