【发布时间】:2014-07-29 16:20:10
【问题描述】:
我的项目使用 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,我必须以特定顺序链接五个目标文件,这需要在ghci Foo之后超过500个字符。
** 更新 **
以下示例说明了为什么以下 n.m. 的解决方案不适用于 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 为空。
步骤:
-
ghci 数
[找不到标签 mulRq]
- gcc -c -o mul.o mul.c
-
ghci mul mul.o
[ghci 加载]
- ghci -fobject-code Dummy
-
ghci 假人
[ghci 加载 编译]
- ld -r Dummy.o mul.o -o temp.o
- mv temp.o Dummy.o
-
ghci 假人
[ghci 加载 编译]
-
nm Dummy.o
[验证 Dummy.o 是否包含符号 mulRq]
现在开始 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
【问题讨论】:
-
使用 shell 脚本而不是
.ghci? -
你可以将对象包装在虚拟 Haskell/ghc 模块中吗?
-
您还可以在per-project basis 上拥有一个
.ghci文件,您可以将其设置为加载该项目所需的目标文件。当你启动 GHCi 时它会全部加载它们,但至少你可以对你正在处理的任何项目进行更多控制,而不必让它们全局化。 -
@n.m.听起来很有趣……我该怎么做?
-
@bheklilr 我确实有一个每个项目的 .ghci 文件。这正是我要问的:如何设置它以在 GHCi 开始时加载目标文件?