写一个模块:
module Foo where
foo = 3.14
编译:
ghc -c Foo.hs
加载它:
ghci -ignore-dot-ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l Foo
[1 of 1] Compiling Foo ( Foo.hs, interpreted )
Ok, modules loaded: Foo.
为什么GHCi不会选择已编译的代码?这是GHCi中的错误吗?
我尝试使用-v
运行,但没有太大帮助。
更新
我发现如果使用GHCi -fobject-code Foo
编译模块,GHCi将随后加载编译版本,即使没有-fobject-code
。
更新2
这一切都发生在Linux机器上的Ghc 7.8上。 Windows机器上的Ghc 7.6没有出现此问题。
答案 0 :(得分:7)
在Linux,FreeBSD和Mac OS X上,GHCi现在使用系统动态 默认情况下是链接器,而不是其内置(静态)对象链接器。 这是更强大的跨平台,并修复了许多长期存在的错误 (例如:构造函数和析构函数,弱符号等工作 正确地说,RTS中的几个边缘情况是固定的。)
因此,GHCi(和模板Haskell)现在必须加载动态 目标文件,而不是静态文件。为了帮助这个,有一个新的 编译标志,-dynamic-too,在编译期间使用 导致GHC同时发出静态和动态目标文件 时间。 GHC本身仍默认为静态链接。 [...]
目前,Windows(32位或64位)不支持动态GHCi和-dynamic-。
最后一句解释了为什么这不影响窗户。
您可以通过比较ghci -fobject-code Foo
和ghc Foo
生成的文件来查看问题:
$ mkdir ghci ghc
$ ghc Foo -odir ghc -hidir ghc
$ ghci -fobject-code Foo -odir ghci -hidir ghci < /dev/null
$ diff -u <(ghc --show-iface ghc/Foo.hi) <(ghc --show-iface ghci/Foo.hi)
--- /proc/self/fd/11 2014-07-30 13:03:34.977845398 +0200
+++ /proc/self/fd/12 2014-07-30 13:03:34.978845419 +0200
@@ -3,13 +3,13 @@
Version: Wanted [7, 0, 8, 3],
got [7, 0, 8, 3]
Way: Wanted [],
- got []
+ got [d, y, n]
interface main:Foo 7083
interface hash: 9aab457c4ecbd2507529fcb479523944
ABI hash: 375e3124c60d5f4eb51e7e38e71a3be0
export-list hash: ff40b932e3d14f0fc26fbd56a58e227c
orphan hash: 693e9af84d3dfcc71e640e005bdc5e2e
- flag hash: 6c2d0082779adc2bd558d879f3f0fe26
+ flag hash: 82fa613fe97939e6767d853897fe1074
used TH splices: False
where
exports:
这表明GHCi将haskell文件编译为动态目标文件(dyn
方式),而
GHC编译为静态目标文件。
当GHCi尝试加载Foo时,它注意到Foo没有可用的动态对象文件(因为GHC生成了静态文件),因此它重新编译Foo。如果给出-fobject-code
,现在将覆盖静态对象文件并生成动态文件,
因此,下次GHCi启动时不需要重新编译。如果-fobject-code
不是
指定,不生成任何对象代码,并以解释模式加载文件。
您还可以告诉ghc
生成动态对象文件:
$ ghc -dynamic -c Foo
现在ghci Foo
不会重新编译Foo,但会使用已编译的动态对象文件。